Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Le déclencheur SQL Server AFTER INSERT ne voit pas la ligne qui vient d'être insérée

Les déclencheurs ne peuvent pas modifier les données modifiées (Inserted ou Deleted ) sinon vous pourriez obtenir une récursivité infinie car les modifications invoquaient à nouveau le déclencheur. Une option serait que le déclencheur annule la transaction.

Modifier : La raison en est que la norme pour SQL est que les lignes insérées et supprimées ne peuvent pas être modifiées par le déclencheur. La raison sous-jacente est que les modifications pourraient provoquer une récursivité infinie. Dans le cas général, cette évaluation pourrait impliquer plusieurs déclencheurs dans une cascade mutuellement récursive. Avoir un système qui décide intelligemment d'autoriser ou non de telles mises à jour est insoluble sur le plan informatique, essentiellement une variante du problème d'arrêt.

La solution acceptée à cela est de ne pas permettre au déclencheur de modifier les données modifiées, bien qu'il puisse annuler la transaction.

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.

Quelque chose comme ça annulera la transaction.

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.