2013-07-18 36 views
3

执行相应的操作我已创建AFTER INSERT触发器如何忽略触发错误和MS SQL Server中

现在,如果如果在执行触发器出现错误无论如何。它不应该在触发表上执行插入操作。

in一个字,如果任何错误发生在触发器中,它应该忽略它。

正如我已经使用

BEGIN TRY 

END TRY 
BEGIN CATCH 

END CATCH 

但它给下面的错误信息并回滚Insert操作上触发表

触发器执行过程中引发错误。该批次已被中止 ,并且用户事务(如果有的话)已被回滚。

+0

你可以发布你的整个代码? –

+0

由于目前在触发代码中没有错误,但为了安全起见,我需要在上线前做同样的事情,所以如果在触发器中发生任何错误,它不会影响插入操作 –

回答

4

有趣的问题。默认情况下,触发器的设计是,如果它们失败了,它们会回滚引发它的命令。所以无论何时触发器执行都有一个活动事务,无论是否有明确的BEGIN TRANSACTION或不在外面。而且BEGIN/TRY里面的触发器也不起作用。您的最佳做法是不写任何可能失败的触发代码 - 除非还希望失败触发语句。

在这种情况下,要抑制此行为,有一些解决方法。

选项A(丑陋的样子):

由于交易是在触发的开始活跃,你可以COMMIT并继续与你的触发命令:

CREATE TRIGGER tgTest1 ON Test1 AFTER INSERT 
AS 
BEGIN 
COMMIT; 
... do whatever trigger does 
END; 

注意,如果触发代码中存在错误,但仍会产生错误消息,但Test1表中的数据已安全插入。

选项B(也难看):

您可以从触发移动你的代码到存储过程。然后从实现BEGIN/TRY的Wrapper SP调用该存储过程,最后 - 从触发器中调用Wrapper SP。如果需要在逻辑中(现在在SP中)需要,可能需要将INSERTED表中的数据移出来,这可能有点棘手 - 可能使用一些临时表。

SQLFiddle DEMO

2

你不能,并且解决它的任何企图是万金油。 TRY/CATCH或@@ ERROR检查将不会解决基本问题。

如果你想使用紧密耦合的触发器,那么你必须购买由耦合引起的较低的可用性。

如果你想保留可用性(即INSERT成功),那么你必须放弃耦合(移除触发器)。您必须在单独的交易中执行您计划在触发器中执行的所有处理,在您执行INSERT后,开始执行之后的。针对新插入的行轮询表的SQL代理作业,Service Broker启动的过程甚至应用程序层步骤都将符合法案要求。