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

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

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

请帮忙!!

【问题讨论】:

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


    【解决方案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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-16
        • 1970-01-01
        • 2011-11-01
        • 1970-01-01
        • 2013-11-29
        • 2023-03-11
        • 2010-11-22
        相关资源
        最近更新 更多