我认为“删除后”意味着在删除已经发生之前触发器才会被触发,但这是我的情况......
在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会给出什么错误。
此外,在触发器代码中的任何位置都没有调用回滚。
答案 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>
您是否已恢复到源代码管理中的最新版本?如果它已经被破坏,也许这将清除问题。