考虑这个触发器:
ALTER TRIGGER myTrigger
ON someTable
AFTER INSERT
AS BEGIN
DELETE FROM someTable
WHERE ISNUMERIC(someField) = 1
END
我有一个表,someTable,我正在努力防止人们插入错误记录。就本问题而言,错误记录有一个全数字的字段“someField”。
当然,正确的方法不是使用触发器,但我不控制源代码......只是 SQL 数据库。所以我无法真正阻止坏行的插入,但我可以立即删除它,这足以满足我的需求。
触发器工作正常,但有一个问题...当它触发时,它似乎永远不会删除刚刚插入的坏记录...它会删除任何旧的坏记录,但不会删除刚刚插入的坏记录。因此,经常会出现一条错误记录,直到其他人出现并执行另一次插入操作后才会将其删除。
这是我对触发器的理解有问题吗?触发器运行时新插入的行是否尚未提交?
最佳答案
触发器无法修改已更改的数据(插入
或删除
),否则当更改再次调用触发器时,您可能会获得无限递归。一种选择是让触发器回滚事务。
编辑:这样做的原因是SQL的标准是插入和删除的行不能被触发器修改。根本原因是修改可能会导致无限递归。在一般情况下,此评估可能涉及相互递归级联中的多个触发器。让系统智能地决定是否允许此类更新在计算上是很困难的,本质上是 halting problem. 的变体。
对此公认的解决方案是不允许触发器更改正在更改的数据,尽管它可以回滚事务。
create table Foo (
FooID int
,SomeField varchar (10)
)
go
create trigger FooInsert
on Foo after insert as
begin
delete inserted
where isnumeric (SomeField) = 1
end
go
Msg 286, Level 16, State 1, Procedure FooInsert, Line 5
The logical tables INSERTED and DELETED cannot be updated.
类似的事情会回滚事务。
create table Foo (
FooID int
,SomeField varchar (10)
)
go
create trigger FooInsert
on Foo for insert as
if exists (
select 1
from inserted
where isnumeric (SomeField) = 1) begin
rollback transaction
end
go
insert Foo values (1, '1')
Msg 3609, Level 16, State 1, Line 1
The transaction ended in the trigger. The batch has been aborted.
关于sql-server - SQL Server "AFTER INSERT"触发器看不到刚刚插入的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/405288/