我在后插入触发器中有一些可能会失败的代码。这样的故障并不重要,应该不回滚事务。如何将错误捕获到触发器中并使事务的其余部分正常执行?
以下示例显示了我的意思。触发器故意创建一个错误条件,结果原始插入(“1”)从不插入表中。尝试/ Catch似乎没有做到这一点。类似的,older stack overflow question没有得出答案,除了“防止错误首先发生” - 这并不总是可行/容易。
还有其他想法吗?
create table test
(
a int not null
);
go
create trigger testTrigger on test
after insert as
begin
insert into test select null;
end;
go
insert into test values ( 1 );
答案 0 :(得分:2)
触发器不会失败并且仍然有事务前滚。您有几个选项可以确保触发器不会失败。
1 - 您可以通过复制用于检查约束的逻辑并且不尝试违反约束的操作来确保after不会失败:
即。
INSERT INTO test WHERE val IS NOT NULL
2 - 您可以使用队列设计模式推迟可能失败的操作,其中可能会或可能不会失败的操作通过排队到排队操作不可能失败的表来排队。
即。
INSERT INTO ACTION_QUEUE (action, parameters) VALUES ('INSERT INTO TEST', val)
答案 1 :(得分:1)
由于SQL Server
中触发器的实现方式,触发器内的所有约束违规都会导致事务失败。
这与做:
相同DROP TABLE test
CREATE TABLE test
(
a INT NOT NULL
)
GO
SET XACT_ABORT ON
GO
BEGIN TRANSACTION
BEGIN TRY
INSERT
INTO test
SELECT NULL
END TRY
BEGIN CATCH
INSERT
INTO test
SELECT 1
END CATCH
导致注定的事务,除了无法在触发器内禁用XACT_ABORT
。
SQL Server
也缺乏自主交易。
这就是为什么你应该将所有逻辑放入存储过程而不是触发器的另一个原因。
答案 2 :(得分:0)