考虑这个触发器:
ALTER TRIGGER myTrigger
ON someTable
AFTER INSERT
AS BEGIN
DELETE FROM someTable
WHERE ISNUMERIC(someField) = 1
END
我有一个表,someTable,我正在努力防止人们插入不良记录。出于这个问题的目的,一个坏记录有一个字段“someField”,它全是数字。
当然,正确的方法不是使用触发器,但我不控制源代码……只是 SQL 数据库。所以我不能真正阻止插入坏行,但我可以立即删除它,这足以满足我的需要。
触发器可以工作,但有一个问题……当它触发时,它似乎永远不会删除刚刚插入的坏记录……它会删除任何旧的坏记录,但不会删除刚刚插入的坏记录。因此,经常有一个不好的记录四处飘散,直到其他人出现并执行另一个 INSERT 时才会删除。
这是我对触发器的理解有问题吗?触发器运行时新插入的行是否尚未提交?
最佳答案
触发器无法修改更改的数据( Inserted
或 Deleted
),否则您可能会在更改再次调用触发器时获得无限递归。一种选择是触发器回滚事务。
编辑: 原因是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/