Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Server AFTER INSERT-Trigger sieht die gerade eingefügte Zeile nicht

Trigger können die geänderten Daten nicht ändern (Inserted oder Deleted ), andernfalls könnten Sie eine unendliche Rekursion erhalten, da die Änderungen den Trigger erneut aufrufen. Eine Option wäre, dass der Trigger die Transaktion rückgängig macht.

Bearbeiten: Der Grund dafür ist, dass der Standard für SQL darin besteht, dass eingefügte und gelöschte Zeilen nicht durch den Trigger geändert werden können. Der zugrunde liegende Grund dafür ist, dass die Änderungen eine unendliche Rekursion verursachen könnten. Im allgemeinen Fall könnte diese Bewertung mehrere Auslöser in einer gegenseitig rekursiven Kaskade beinhalten. Ein System intelligent entscheiden zu lassen, ob es solche Aktualisierungen zulässt, ist rechnerisch schwer zu bewältigen, im Wesentlichen eine Variation des Halting-Problems.

Die akzeptierte Lösung dafür besteht darin, dem Trigger nicht zu erlauben, die sich ändernden Daten zu ändern, obwohl er die Transaktion rückgängig machen kann.

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.

So etwas wird die Transaktion rückgängig machen.

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.