首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TSQL使触发器无声地失败

TSQL使触发器无声地失败
EN

Stack Overflow用户
提问于 2010-01-29 15:34:52
回答 3查看 8.1K关注 0票数 7

我在一个后插入触发器中有一些可能会失败的代码。这样的失败并不重要,也不应该回滚事务。如何在触发器中捕获错误并让事务的其余部分正常执行?

下面的例子说明了我的意思。触发器故意创建一个错误条件,其结果是原始insert ( "1“)永远不会插入到表中。尝试/抓住似乎没有起作用。类似的,older stack overflow question没有给出一个答案,除了“首先防止错误发生”--这并不总是可能的/容易的。

还有其他想法吗?

代码语言:javascript
复制
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 );
EN

回答 3

Stack Overflow用户

发布于 2010-01-29 15:44:41

触发器不能失败,并且仍然让事务前滚。您有几个选项可以确保触发器不会失败。

1-通过重复检查约束的逻辑和不尝试违反约束的操作,可以确保after不会失败:

代码语言:javascript
复制
INSERT INTO test WHERE val IS NOT NULL

2-您可以通过使用队列设计模式来延迟可能失败的操作,在队列设计模式中,可能或不可能失败的操作通过排队到一个表中,在该表中,登记操作不可能失败。

代码语言:javascript
复制
INSERT INTO ACTION_QUEUE (action, parameters) VALUES ('INSERT INTO TEST', val)
票数 3
EN

Stack Overflow用户

发布于 2010-01-29 17:05:42

由于触发器在SQL Server中的实现方式,触发器中所有违反约束的行为都会导致事务失败。

这与做以下工作一样:

代码语言:javascript
复制
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也缺乏自主事务。

这也是为什么应该将所有逻辑都放入存储过程而不是触发器中的另一个原因。

票数 1
EN

Stack Overflow用户

发布于 2012-05-01 18:29:53

  1. 您可以在触发器内关闭XACT_ABORT (请注意)
  2. ,您可以让触发器调用一个存储过程。(我现在正努力解决相反的问题:我希望事务中止,但由于逻辑位于从触发器调用的SP中,而不是触发器本身,所以这没有发生。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2162966

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档