更新表上的触发器

时间:2013-12-10 16:34:21

标签: sql sql-server-2008 stored-procedures triggers informix

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

我在更新之后有一个代码“如果是Sqlca.SqlCode”,并且这个代码总是有0来进行更新。

请帮助!!

2 个答案:

答案 0 :(得分:2)

是的,如果触发器遇到错误(内部或通过调用某些外部过程)并回滚事务,它将回滚整个事务,包括导致触发器触发的任何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

结果:

  

Msg 8134,Level 16,State 1,Procedure oh_my   
遇到零误差。   该声明已经终止。

然而,SELECT显示,即使触发器中发生错误, UPDATE提交后也发生了错误 - 因此不同于AFTER触发器(没有正确的错误处理),我们能够防止错误回滚我们已完成的所有工作。

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

答案 1 :(得分:1)

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

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

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