4

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

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

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

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


编辑:

感谢您提供有关通过使用触发器以外的其他东西来优化性能的提示,但是从长时间运行或性能密集型的意义上说,这段代码并不“复杂”;它只是构建并发送邮件消息,但为了做到这一点,它必须从各种链接表中检索数据,并且由于我正在对该应用程序进行逆向工程,因此我没有可用的数据库模式并且仍在尝试查找我绕着它走;这就是为什么转换错误或意外/空值仍然会蔓延,导致触发器执行崩溃的原因。

另外,如上所述,我绝对不能对应用程序本身进行调试,也不能修改它以在应用程序层做我需要的事情;对应用程序事件做出反应的唯一方法是在应用程序向数据库写入刚刚发生的事情时触发数据库触发器。

4

2 回答 2

2

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

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

如果这看起来太复杂,那么较旧的方法是将需要处理的行插入工作/队列表中,然后有一项工作不断地从那里拉出正在做的工作。

无论哪种方式,您现在都不会阻止原始事务提交。

于 2012-05-05T15:02:13.103 回答
0

触发器是事务的一部分。您可以尝试在触发器代码周围捕获燕子,或者更专业地尝试捕获日志燕子,但实际上您应该让它爆炸,然后解决只能在您的触发器中的真正问题。如果以上都不可接受,则不能使用触发器。

于 2012-05-05T14:45:04.727 回答