トランザクション内でサーバーに対してsqlファイルの内容を実行する必要があります。ファイルにはGO文で区切られたバッチが含まれているため、T-SQL TRY-CATCH ROLLBACKは実行されません。PowershellからトランザクションでGOで区切られたSQLバッチを実行する
System.Transactions.TransactionScope
と組み合わせて使用されていることを除いて、例外はそのトランザクションのみが中止され、有用な情報は出力されません(内部例外のチェックなし、何もありません)。
System.Data.SqlClient.SqlConnection
トランザクションをSystem.Data.SqlClient.SqlCommand
と組み合わせて使用してみましたが、これはうまく機能しますが、GO文ではうまくいきます。
Microsoft.SqlServer.Management.Smo.Server
オブジェクトを使用する最適な解決法はありますが、私は奇妙な問題があり、すべての行を別々のバッチとして扱うことができます。
コード:
$server = New-Object Microsoft.SqlServer.Management.Smo.Server($databaseServer)
$server.ConnectionContext.ConnectionString = $connectionString
$script = Get-Content "$sqlScriptsPath\$scriptName.sql"
try
{
$server.ConnectionContext.BeginTransaction()
$server.ConnectionContext.ExecuteNonQuery($script)
$server.ConnectionContext.CommitTransaction()
}
catch
{
$server.ConnectionContext.RollBackTransaction()
throw
}
ファイルは1行のステートメント(私は挿入でそれをテストしています)でのみ構成されている場合、それは[OK]を動作しますが、コマンドが複数行ある時はいつでも、それは何かをoutputingチョーク「不適切な構文のように」)何か、文脈に応じて。
例:スローされます
DECLARE @msg varchar(50) = 'test'
PRINT @msg
が
@msg "スカラー変数を宣言する必要があります ""。"
しかし、ファイルに ';'で区切られた両方のコマンドが1行に含まれていると、できます。
私は明らかにしようとしました:$server.ConnectionContext.BatchSeparator = 'GO'
しかし、 'GO'は既にデフォルトセパレータであるため、何も変わりません。
感謝。 Hovewer、私はGOで分割する予定ですが、私はSystem.Data.SqlClient.SqlConnectionとSystem.Data.SqlClient.SqlCommandを使用しています。これははるかに一般的で堅牢です。そしてこのようにGOで分割しないでください。文字列と変数名に "GO"を付けることができます!^\ s * GO \ s *($ | \ - \ *。*)(ソース:https://stackoverflow.com/q/27301225/3922292)のような少なくとも正規表現を使用してください。 –