如何处理触发器中的错误?

时间:2012-05-05 14:30:37

标签: sql sql-server error-handling triggers sql-server-2008-r2

我正在编写一些在数据库表中插入行时需要执行的SQL代码,所以我使用的是AFTER INSERT触发器;代码非常复杂,因此仍然可能存在一些错误。

我发现,如果在执行触发器时发生错误,SQL Server将中止批处理和/或整个事务。这对我来说是不可接受的,因为它会给使用数据库的主应用程序带来问题;我也没有该应用程序的源代码,因此我无法对其进行适当的调试。即使我的触发器失败,我也绝对需要所有数据库操作才能成功。

如何对触发器进行编码,以便在发生错误时,SQL Server 中止INSERT操作?

此外,如何执行正确的错误处理,以便我实际上可以知道触发器已失败?发送带有错误数据的电子邮件对我来说是好的(触发器的主要目的实际上是发送电子邮件),但是如何在触发器中检测错误情况并对其做出反应?


编辑:

感谢有关通过使用除触发器之外的其他内容来优化性能的提示,但是这段代码在长期运行或性能密集的意义上并非“复杂”;它只是构建和发送邮件消息,但为了做到这一点,它必须从各种链接表中检索数据,因为我正在逆向工程这个应用程序,我没有可用的数据库模式,我仍然试图找到我的方式;这就是为什么转换错误或意外/空值仍然会爬升,导致触发器执行崩溃的原因。

另外,如上所述,我绝对无法对应用程序本身进行调试,也不能修改它以在应用程序层中执行我需要的操作;对应用程序事件作出反应的唯一方法是在应用程序向DB写入某些内容刚刚启动时触发数据库触发器。

2 个答案:

答案 0 :(得分:2)

如果触发器中的操作很复杂和/或可能长时间运行,并且您不希望活动影响原始事务,那么您需要找到一种解耦活动的方法。

一种方法可能是使用Service Broker。在触发器中,只需创建消息(每行一个)并在途中发送它们,然后在服务中执行其余的处理。

如果这看起来过于复杂,那么较旧的方法是将需要处理的行插入到工作/队列表中,然后让一个工作从那里继续拉动行。

无论哪种方式,您现在都没有阻止原始交易提交。

答案 1 :(得分:0)

触发器是交易的一部分。您可以尝试在触发器代码周围尝试捕获,或稍微更专业的尝试捕获日志吞下,但实际上你应该让它发出爆炸然后修复真正的问题,这只能在你的触发器中。 如果以上都不可接受,那么就不能使用触发器。