更新表上的触发器[关闭]

Posted

技术标签:

【中文标题】更新表上的触发器[关闭]【英文标题】:Update Trigger on a Table [closed] 【发布时间】:2013-12-10 16:34:20 【问题描述】:

如果表 A 更新,则触发触发器。该触发器调用另一个 SP 进行一些处理。 如果 SP 失败,表 A 上发生的更新是否有可能被恢复?

我在更新“If Sqlca.SqlCode”之后有一个代码,更新时总是有 0。

请帮忙!!

【问题讨论】:

【参考方案1】:

是的,如果触发器遇到错误(内部或通过调用某些外部过程)并回滚事务,它将回滚整个事务,包括首先导致触发器触发的UPDATE。如果不是您想要的行为,有多种方法可以解决此问题:

使用TRY / CATCH 吸收来自外部过程的任何错误,或者将过程逻辑移到触发器中,或者为存储过程添加适当的错误处理,这样,如果您不在乎发生错误在那里,它不会冒泡并回滚所有内容。

使用INSTEAD OF 触发器 - 结合TRY / CATCH(或者可能先提交您自己的UPDATE),您应该能够更新表而无需关心外部存储过程是否失败。

INSTEAD OF 触发器示例:

USE tempdb;
GO

CREATE TABLE dbo.flooblat(id INT PRIMARY KEY, name VARCHAR(32));
INSERT dbo.flooblat(id,name) VALUES(1, 'Bob');
GO

CREATE PROCEDURE dbo.oh_my
AS
  SELECT 1/0;
GO

CREATE TRIGGER dbo.trFlooblat
  ON dbo.flooblat
  INSTEAD OF UPDATE
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE f SET f.name = i.name
    FROM dbo.flooblat AS f
    INNER JOIN inserted AS i
    ON f.id = i.id;

  COMMIT TRANSACTION;

  EXEC dbo.oh_my;
END
GO

UPDATE dbo.flooblat SET name = 'Frank';
GO

SELECT id, name FROM dbo.flooblat;
GO

结果:

消息 8134,级别 16,状态 1,过程 oh_my 遇到除以零错误。 声明已终止。

然而,SELECT 表明,即使触发器中发生错误,它也发生在UPDATE 提交之后 - 与AFTER 触发器中发生的异常不同(没有适当的错误处理),我们能够防止错误回滚我们所做的所有工作。

id    name
----  -----
1     Frank

【讨论】:

【参考方案2】:

触发器可以在执行 DML 之后执行操作,而不是执行 DML 等。所以是的,如果 SP 失败,更新 (dml) 不会 发生的机会 - 只是取决于您如何编写它/您使用什么功能。

在这里阅读一下触发器:http://technet.microsoft.com/en-us/library/ms189799%28v=sql.105%29.aspx

如果您想在问题中获得更具体的触发器答案,那么您需要发布代码。

【讨论】:

以上是关于更新表上的触发器[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

创建一个触发器,当另一个表中的列更新时更新一个表上的列

在高并发写入表上使用触发器防止死​​锁错误

如果更新,则在同一张表上执行触发器

更新时在同一张表上执行触发器

而不是所有表上的插入触发器

两个不同表上的 ORACLE SQL 触发器或存储过程