TSQL:触发器中的Try-Catch事务

Eld*_*ila 14 t-sql sql-server triggers

我试图在使用Microsoft Server 2005的触发器中放置一个try-catch语句.

BEGIN TRANSACTION
BEGIN TRY
    --Some More SQL
    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    IF (XACT_STATE()) = -1
    BEGIN
        ROLLBACK TRANSACTION;
    END;
END CATCH
Run Code Online (Sandbox Code Playgroud)

问题是,如果try-catch块捕获了某些内容,我不希望触发器失败.目前,我收到错误"交易在触发器中结束.批次已中止." 如果交易失败.如何让触发器优雅地失败?


另外,如果我删除了该事务,我会收到错误"事务在触发器中注定.批处理已中止.".

BEGIN TRY
    --Some More SQL
END TRY
BEGIN CATCH
    return
END CATCH
Run Code Online (Sandbox Code Playgroud)

有没有办法解决?

gbn*_*gbn 8

不要在触发器中回滚,也不需要启动事务.

ROLLBACK TRANSACTION会回滚原来的DML触发器额外的触发交易了.因此批次将被中止

编辑:

我建议你的catch块中没有"RETURN",只是允许代码完成我从来没有忽略过触发器中的陷阱错误(但我确实在触发器中使用TRY/CATCH并使用rollback和raiserror来重新抛出)所以这是猜测,但返回可能是触发器中的异常退出条件

另外,首先尝试避免错误情况.更改--some more sql以避免错误.例如,添加if exists(...以测试重复的第一个或类似的


u07*_*7ch 8

根据我的经验,触发器中的try catch中捕获的任何错误都将回滚整个事务; 您可以使用保存交易.我想你需要看一下"Some more sql"中发生的事情,并确定你是否可以编写case/if语句以阻止错误.

根据你正在做的事情,你可以做的就是使用保存事务并捕获它

在你的代码中这样的东西

SAVE TRANSACTION BeforeUpdate;
BEGIN TRY
        --Some More SQL
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION BeforeUpdate;
        return
END CATCH
Run Code Online (Sandbox Code Playgroud)


神來之*_*來之筆 6

使用 SET XACT_ABORT OFF 。当 Transact-SQL 语句遇到错误时,它只是引发错误消息,事务继续处理。以下代码是创建触发器:

Create TRIGGER [dbo].tr_Ins_Table_Master ON [dbo].Table_Master
 AFTER INSERT
AS
BEGIN
set xact_abort off
BEGIN TRY
        --your SQL          
        INSERT INTO Table_Detail
        SELECT MasterID,Name FROM INSERTED

END TRY

BEGIN CATCH     
    select ERROR_MESSAGE()
END CATCH

END
Run Code Online (Sandbox Code Playgroud)