SQL Server “AFTER INSERT” trigger doesn't see the just-inserted row

后端 未结 12 1994
庸人自扰
庸人自扰 2020-12-23 14:05

Consider this trigger:

ALTER TRIGGER myTrigger 
   ON someTable 
   AFTER INSERT
AS BEGIN
  DELETE FROM someTable
         WHERE ISNUMERIC(someField) = 1
END         


        
12条回答
  •  一个人的身影
    2020-12-23 14:35

    Triggers cannot modify the changed data (Inserted or Deleted) otherwise you could get infinite recursion as the changes invoked the trigger again. One option would be for the trigger to roll back the transaction.

    Edit: The reason for this is that the standard for SQL is that inserted and deleted rows cannot be modified by the trigger. The underlying reason for is that the modifications could cause infinite recursion. In the general case, this evaluation could involve multiple triggers in a mutually recursive cascade. Having a system intelligently decide whether to allow such updates is computationally intractable, essentially a variation on the halting problem.

    The accepted solution to this is not to permit the trigger to alter the changing data, although it can roll back the 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.
    

    Something like this will roll back the 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.
    

提交回复
热议问题