SQL Serverに大量データをインサートする場合、Bulk Insertをよく利用しています。
利用するたびにSQL Server Management Studioを起動していますが、環境によっては起動が遅いので困っています。
より早く、簡単、そして手軽に実行するためSQL Server PowerShell を使ってBulk Insertを実行するサンプルを書いてみました。
利用するたびにSQL Server Management Studioを起動していますが、環境によっては起動が遅いので困っています。
より早く、簡単、そして手軽に実行するためSQL Server PowerShell を使ってBulk Insertを実行するサンプルを書いてみました。
2015.04.19 加筆
New-PSDrive コマンドレットに-Credential パラメーターを追記しました。
New-PSDrive コマンドレットに-Credential パラメーターを追記しました。
やりたい事
- Windows クライアントから、大量のCSVファイルをSQL Serverにインポートしたい
- インポートはBulk Insertを使いたい
事前環境
- Windows クライアントでSQL Server PowerShellが実行できる事
- 共有フォルダーへ接続できる事
フロー
- 共有フォルダーに接続
- 共有フォルダーにCSVファイルをコピー
- 全CSVファイルパスを取得
- Bulk Insertを実行
- インポートが完了後、ファイルの拡張子をリネーム
- 共有フォルダーを切断
サンプル
Windows クライアントからBulk Insertを実行するため、Invoke-Sqlcmd コマンドレットを使います。
$ServerName = '<サーバー名>'
$FolderPath = "\\$ServerName\<共有フォルダー名>"
$PsDrive = "<ドライブ名>"
$Table = "[<データベース名>].[<スキーム名>].[<テーブル名>]"
$RenameExtention = "<拡張子名>"
$Cnt = 1
Write-Host "Bulk Insertを開始します" -ForegroundColor Cyan
#共有フォルダーに接続
try
{
if((Test-Path "$PsDrive`:") -eq $false)
{
#New-PSDrive コマンドレットは、環境によって-Credential パラメーターを付けてください。
$tmp = New-PSDrive -Name $PsDrive -PSProvider FileSystem -Root $FolderPath
Write-Debug "共有フォルダーに接続しました"
#Copy Files
Copy-Item -Path "<ローカル パス>\<ファイル>" -Destination $PsDrive
}
}
catch [Exception]
{
Write-Host "エラー:パスが存在しません。" -BackgroundColor Yellow
exit
}
#Get Files
$files = gci "$PsDrive`:" -Exclude "*.$RenameExtention" -Recurse -ErrorAction Stop
Write-Debug "対象ファイルを取得しました"
foreach($f in $files)
{
#Bulk Insert SQL
$s = @"
BULK INSERT $Table
FROM "$f" WITH (
FIELDTERMINATOR = '\t'
, ROWTERMINATOR = '\n'
, FIRSTROW = 2)
"@
try
{
#Exec SQL
Invoke-Sqlcmd -Query $s -ServerInstance $ServerName
Write-Host " `#$Cnt Import Finished!!"
#Rename Extention
Rename-Item -Path $f -NewName ($f -replace '.txt$', ".$RenameExtention")
Write-Debug " 拡張子をリネームしました"
$Cnt += 1
}
catch [Exception]
{
Write-Host "エラーが発生しました" -ForegroundColor Yellow
Write-Host $Error -ForegroundColor Yellow
exit
}
}
#Remove PSDrive
if((Test-Path $FolderPath) -eq $true)
{
Remove-PSDrive -Name $PsDrive -Force
Write-Debug "共有フォルダーを切断しました"
}
Write-Host "完了しました" -ForegroundColor Cyan