代码之家  ›  专栏  ›  技术社区  ›  Brandi

删除后触发器仅在删除后触发?

  •  1
  • Brandi  · 技术社区  · 16 年前

    我认为“删除后”意味着直到删除已经发生后才会触发,但这里是我的情况…

    我在c_中创建了3个几乎相同的sql clr after delete触发器,工作了大约一个月。突然,三个程序中的一个在运行自动删除工具时停止工作。

    我的意思是,停止工作不能通过客户端软件从表中删除记录。禁用触发器会导致允许删除,但重新启用触发器会干扰删除功能。

    所以我的问题是“怎么会这样?”上面使用的工具有没有可能使记忆更丰富?似乎即使触发器抛出了异常,如果是在delete之后,记录不应该消失吗?

    所有的触发器都是这样的:

    ALTER TRIGGER [sysdba].[AccountTrigger] ON [sysdba].[ACCOUNT]  AFTER  DELETE AS 
    EXTERNAL NAME [SQL_IO].[SQL_IO.WriteFunctions].[AccountTrigger]
    GO
    

    CLR触发器执行一次选择并将一次插入另一个数据库。我还不知道sqlservermgmtstudio是否有任何错误,但在我发现后会更新这个问题。

    更新:

    好吧,在重新执行上述相同的触发代码之后,一切都会重新工作,所以我可能永远不知道ssms会给出什么错误。

    此外,触发器的代码中没有回滚的调用。

    3 回复  |  直到 14 年前
        1
  •  6
  •   SQLMenace    16 年前

    after意味着它只是在事件发生后触发,仍然可以回滚

    例子

    create table test(id int)
    go
    
    
    create trigger trDelete on test after delete
    as
    
    print 'i fired '
    rollback
    

    做一个插入

    insert test values (1)
    

    现在删除数据

    delete test
    

    这是触发器的输出

    我开枪了

    消息3609,级别16,状态1,行1

    事务在触发器中结束。批处理已中止。

    现在检查表,确认没有删除任何内容

    select * from test
    

    clr触发器执行一个select和 一次插入另一个数据库。我 还不知道有没有错误 来自SQL Server管理工作室,但将 在我发现后更新问题。

    突然,三个人中的一个停了下来 使用自动删除工具 是在上面跑的。

    触发器按批触发/语句而不是按行触发,是否可能触发器不是为多行操作编码的,并且自动工具删除了批中的多行?看一看 Best Practice: Coding SQL Server triggers for multi-row operations

    下面是一个不执行显式回滚而使触发器失败的示例

    alter trigger trDelete on test after delete
    as
    
    print 'i fired '
    declare @id int
    select @id = (select id from deleted)
    GO
    

    插入一些行

    insert test values (1)
    insert test values (2)
    insert test values (3)
    

    运行此

    删除测试
    

    我开枪了 消息512,级别16,状态1,过程trdelete,第6行

    子查询返回的值超过1个。当子查询跟随=,,时不允许这样做!=,<,<=,>,>=或当子查询用作表达式时。

    声明已终止。

    检查桌子

    从测试中选择*
    

    未删除任何内容

        2
  •  1
  •   Martin Smith    16 年前

    after delete触发器中的错误将回滚事务。这是在删除它们之后,但在提交更改之前。您使用CLR触发器有什么特殊原因吗?看起来,纯sql触发器应该能够以一种可能更轻量级的方式执行。

        3
  •  1
  •   HLGEM    16 年前

    好吧,你不应该做一个select-in触发器(谁会看到结果),如果你所做的只是一个insert,那么它也不应该是一个clr触发器。clr通常不是触发器中的好东西,除非您需要做一些t-sql无法处理的事情,否则最好在触发器中使用t-sql代码。

    是否已还原到源代码管理中的最新版本?如果问题已经被破坏了,也许这会解决问题。