Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

O gatilho AFTER INSERT do SQL Server não vê a linha recém-inserida


Os gatilhos não podem modificar os dados alterados (Inserted ou Deleted ) caso contrário, você pode obter recursão infinita, pois as alterações invocam o gatilho novamente. Uma opção seria o gatilho reverter a transação.

Editar: A razão para isso é que o padrão para SQL é que as linhas inseridas e excluídas não podem ser modificadas pelo gatilho. A razão subjacente é que as modificações podem causar recursão infinita. No caso geral, essa avaliação pode envolver vários gatilhos em uma cascata mutuamente recursiva. Ter um sistema que decida inteligentemente se permite tais atualizações é computacionalmente intratável, essencialmente uma variação do problema de interrupção.

A solução aceita para isso é não permitir que o gatilho altere os dados alterados, embora possa reverter a transação.
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.

Algo assim reverterá a transação.
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.