using System;
using System.Data.SqlClient;
using System.IO;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
namespace ScriptRunner
{
class Program
{
static void Main(string[] args)
{
var script = File.ReadAllText("Test.sql");
const string sqlConnectionString = @"Data Source=my\ds;
Initial Catalog=myic;
Connection Timeout=0;
Integrated Security=true";
SqlConnection connection = null;
Server server = null;
try
{
connection = new SqlConnection(sqlConnectionString);
server = new Server(new ServerConnection(connection));
server.ConnectionContext.BeginTransaction();
server.ConnectionContext.ExecuteNonQuery(script);
server.ConnectionContext.CommitTransaction();
}
catch { server.ConnectionContext.RollBackTransaction(); }
finally { connection?.Dispose(); }
}
}
}
代码完美无缺,除非错误为fatal。
我的意思是致命的: 当在Test.sql中时,有:
insert into TestTable (result) values ('transaction commited')
raiserror('tset', 17, -1) with log
它有效 - 事务被回滚,在TestTable中没什么新东西
但是当Test.sql内部是致命的raiserror(20)时:
insert into TestTable (result) values ('transaction commited')
raiserror('tset', 20, -1) with log
将插件提交到数据库,就像没有事务一样。
这是问题How to use transactions in SMO.Server ConnectionContext的衍生产品,我在脚本中遇到致命错误,并认为交易根本不起作用。
问题:如何使此代码处理致命错误? 感谢。
答案 0 :(得分:0)
问题是致命错误应该终止进程,终止连接。由于XACT_ABORT未设置为ON,行为如上所述(尽管如此,我还是希望事务挂起......)。在脚本开头设置SET XACT_ABORT ON可以解决问题。参考文献: