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

时间:2010-05-05 14:40:27

标签: sql sql-server sql-server-2008 tsql sqlclr

我认为“删除后”意味着在删除已经发生之前触发器才会被触发,但这是我的情况......

在C#中删除触发器后,我创建了3个几乎相同的SQL CLR,它工作了大约一个月。突然,三个中的一个停止工作,同时在其上运行自动删除工具。

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

所以我的问题是'这怎么可能?'它上面使用的工具是否有可能在记忆中充满活力?似乎即使触发器抛出异常,如果它是删除后,记录不应该消失吗?

所有触发器都是这样的:

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

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

更新:

在重新执行上面相同的触发器代码之后,一切都再次起作用,所以我可能永远不知道SSMS会给出什么错误。

此外,在触发器代码中的任何位置都没有调用回滚。

3 个答案:

答案 0 :(得分:6)

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

例如

create table test(id int)
go


create trigger trDelete on test after delete
as

print 'i fired '
rollback

进行插入

insert test values (1)

现在删除数据

delete test

以下是触发器的输出

我解雇了

Msg 3609,Level 16,State 1,Line 1

交易在触发器中结束。批次已中止。

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

select * from test
  

CLR触发器执行一个选择和   一个插入另一个数据库。一世   还不知道是否有任何错误   来自SQL Server Mgmt Studio,但是会   我发现后更新问题。

     

突然,三人中的一人停了下来   在自动删除工具时工作   在它上面运行。

每个批次/语句不会触发每行触发,是否可能没有为多行操作编码触发器,并且自动化工具在批处理中删除了多于一行?看看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)

运行此

delete test
我解雇了 Msg 512,Level 16,State 1,Procedure trDelete,Line 6

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

声明已经终止。

检查表格

select * from test

没有删除

答案 1 :(得分:1)

AFTER DELETE触发器中的错误将回滚事务。它是在删除之后但在提交更改之前。您是否有任何特殊原因使用CLR触发器?看起来纯粹的SQL触发器应该能够以更轻量级的方式执行。

答案 2 :(得分:1)

那么你不应该在触发器中进行选择(谁会看到结果),如果你所做的只是一个插入,它也不应该是一个CLR触发器。 CLR在触发器中通常不是一件好事,在触发器中使用t-SQL代码要好得多,除非你需要做一些t-sql无法处理的事情,这在触发器中可能是个坏主意。< / p>

您是否已恢复到源代码管理中的最新版本?如果它已经被破坏,也许这将清除问题。