【发布时间】:2017-11-08 15:42:05
【问题描述】:
我需要针对服务器内部事务运行 sql 文件的内容。该文件包含由 GO 语句分隔的批次,因此 T-SQL TRY-CATCH ROLLBACK 是不行的。
Invoke-Sqlcmd -InputFile 完美运行,除了与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
}
当文件仅包含单行语句(我正在使用插入测试它)时,它可以正常工作,但是只要命令是多行的,它就会阻塞输出类似“')'附近的语法错误”。或其他东西,取决于上下文。
例如:
DECLARE @msg varchar(50) = 'test'
PRINT @msg
会抛出“必须声明标量变量“@msg”。”
但是当文件在一行中包含两个命令时,由 ';' 分隔它有效。
我尝试了明显的:$server.ConnectionContext.BatchSeparator = 'GO',但它没有任何改变,因为“GO”已经是默认分隔符。
【问题讨论】:
标签: sql-server powershell transactions