sql >> Base de Datos >  >> RDS >> Sqlserver

SQL Server DESPUÉS de INSERTAR disparador no ve la fila recién insertada

Los activadores no pueden modificar los datos modificados (Inserted o Deleted ) de lo contrario, podría obtener una recursividad infinita ya que los cambios invocaron el disparador nuevamente. Una opción sería que el activador revirtiera la transacción.

Editar: La razón de esto es que el estándar para SQL es que las filas insertadas y eliminadas no pueden ser modificadas por el disparador. La razón subyacente es que las modificaciones podrían causar una recursividad infinita. En el caso general, esta evaluación podría implicar múltiples disparadores en una cascada mutuamente recursiva. Tener un sistema que decida de manera inteligente si permitir tales actualizaciones es computacionalmente intratable, esencialmente una variación del problema de detención.

La solución aceptada para esto es no permitir que el disparador altere los datos cambiantes, aunque puede revertir la transacción.

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 como esto revertirá la transacción.

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.