Тригерите не могат да променят променените данни (Inserted
или Deleted
) в противен случай бихте могли да получите безкрайна рекурсия, тъй като промените извикват отново тригера. Една от опциите би била тригерът да върне транзакцията назад.
Редактиране: Причината за това е, че стандартът за SQL е, че вмъкнатите и изтритите редове не могат да бъдат модифицирани от тригера. Основната причина е, че модификациите могат да причинят безкрайна рекурсия. В общия случай тази оценка може да включва множество тригери във взаимно рекурсивна каскада. Наличието на система, която интелигентно решава дали да разреши такива актуализации, е изчислително неразрешимо, по същество вариант на проблема със спирането.
Приетото решение за това е да не се позволява на тригера да променя променящите се данни, въпреки че може да върне обратно транзакцията.
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.