我有很多使用 CLR 过程的 MSSQL 脚本。.NET 代码处理 SQL 异常并在它们绕过 SQL 错误处理时通知它们。问题是,如果 CLR 抛出未得到处理的异常,SLQ 脚本会将其写入消息窗口并继续执行脚本,就像什么都没发生一样。如何从 CLR 抛出“致命的”T-SQL 异常?
2 回答
对于这种特殊情况,我有多个使用 CLR 过程的脚本,它不是遍历每个脚本并编辑它们的最佳解决方案,因为它可能会引发不可预测的行为。我发现这三个解决方案很有用。
I.set xact_abort on
使 CLR 在出错时停止并回滚当前事务。如何使用它有多种变化。(在每次调用或整个数据库之前)这也不是最好的解决方案,因为我不想编辑所有出现的过程并且在整个数据库上设置 xact_abort 可能会做一些不可预测的事情。
二、重命名现有的 CLR 过程。创建具有与重命名之前的 CLR 过程相同的参数和名称的新过程。将此代码放入新的过程调用中。
set xact_abort on
exec renamed_clr_procedure @arg1=v1, @arg2=v2, ...
set xact_abort off
还可以检查 xact_abort 是否已经设置在首位。那么我们应该只调用renamed_clr_procedure。
三、因为我注意到,所有 SQL 过程(包含 CLR 过程)调用都来自一个地方,在我执行过程之前,我set xact_abort on
在过程之前和set xact_abort off
之后调用。
我认为抛出“致命”异常是不可取的。相反,您应该由 TSQL 决定退出是否正确。您经常需要释放资源,例如应用程序锁。
这是 TSQL 中异常处理的文档:http: //msdn.microsoft.com/en-us/library/ms175976.aspx
如果您只想死于任何异常,请将现有代码包装在一个空的 try catch 块中:
BEGIN TRY
existing statements
END TRY BEGIN CATCH END CATCH;