繁体   English   中英

如何忽略触发器中的错误并在MS SQL Server中执行相应的操作

[英]How to Ignoring errors in Trigger and Perform respective operation in MS SQL Server

我创建了AFTER INSERT TRIGGER

现在,如果在执行Trigger时发生错误,则为任何情况。 它不应该影响触发表上的插入操作。

如果在触发器中发生任何ERROR,则应该忽略它。

正如我用过的那样

BEGIN TRY

END TRY
BEGIN CATCH

END CATCH

但是它会在Triggered表上给出以下错误消息和Rolled back Insert操作

触发器执行期间出错。 批处理已中止,并且已回滚用户事务(如果有)。

有趣的问题。 默认情况下,设计触发器,如果​​它们失败,则会回滚触发它的命令。 因此,无论何时执行触发器,都存在活动事务,无论外部是否存在明确的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

你不能,任何解决它的尝试都是蛇油。 任何数量的TRY / CATCH或@@ ERROR检查都不会解决根本问题。

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

如果要保留可用性(即INSERT成功),则必须放弃耦合(删除触发器)。 您必须 INSERT提交启动的单独事务中执行您计划在触发器中执行的所有处理。 一个SQL代理作业轮询表中新插入的行,Service Broker启动的过程甚至应用程序层步骤都符合要求。

接受的答案选项A给了我以下错误:“事务在触发器中结束。批处理已中止。” 我使用下面的SQL来规避问题。

CREATE TRIGGER tgTest1 ON Test1 AFTER INSERT
AS
BEGIN
    SET XACT_ABORT OFF
    BEGIN TRY  
        SELECT [Column1] INTO #TableInserted FROM [inserted]
        EXECUTE sp_executesql N'INSERT INTO [Table]([Column1]) SELECT [Column1] FROM #TableInserted'
    END TRY  
    BEGIN CATCH
    END CATCH
    SET XACT_ABORT ON
END

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM