PowerShellで次のことを行う方法の例がオンラインでたくさん見つかりました:
Get-ChildItem $databaseFolder -Filter *.sql -Recurse | ForEach-Object { sqlcmd -S $databaseServer -d $databaseName -E -i $_.FullName }
ただし、これを 1 つのトランザクションにグループ化したいので、SQL ファイルの 1 つが失敗した場合、すべてがロールバックされます。
私が試している代替手段の 1 つは、すべてのファイルの内容を完全なスクリプト変数にまとめることです。
foreach( $file in Get-ChildItem -path $databaseFolder -Filter *.sql | sort-object )
{
Get-Content $file.fullName | Foreach-Object { $fullSqlScript = $fullSqlScript + $_ + "`n" } ;
}
そして、最後に次のように実行します。
invoke-sqlcmd -ServerInstance $databaseServer -Database $databaseName -Query $fullSqlScript | format-table | out-file -filePath $outFile
$fullSqlScript には、先頭に次のコードも挿入されます。
:On Error Exit
SET XACT_ABORT ON
GO
Begin Transaction
そして終わり:
IF XACT_STATE() = 1
BEGIN
PRINT 'Committing Transaction...'
COMMIT TRANSACTION
END
ELSE IF XACT_STATE() = -1
BEGIN
PRINT 'Scripts Failed... Rolling back'
ROLLBACK TRAN
END
ただし、意図的なSQLスクリプトを失敗させるとすぐに、トランザクションをロールバックできないようにデータベース全体がロックされます。これは、Windowsコマンドプロンプトからのsqlcmdではなく、powershellスクリプト環境で使用されているinvoke-sqlcmdと関係があると思いますか?