2010-01-05 14 views
9

Escribí un disparador que debe hacer un trabajo diferente en una tabla en función de qué columnas en una fila se actualizaron realmente. Lo logré usandoTSql Trigger debe disparar solo en las columnas cuyos valores han cambiado

IF UPDATE(column-name) 

Esa parte funciona bien. Sin embargo, resulta que hay otras partes del código que actualizan las filas al establecer cada valor individual, independientemente de si el valor realmente cambió o no, y esto hace que el desencadenador se active para las partes que fueron "actualizadas" pero cuyos valores realmente no cambiaron en absoluto.

Como cambiar el código que está causando esto probablemente no es una opción, ¿hay alguna manera más fácil de evitar esto que tener que comparar las tablas INSERTADA y ELIMINADA (en cuyo caso las ACTUALIZACIONES DE IF no tienen sentido)?

Respuesta

14
IF EXISTS (SELECT * 
      FROM 
      INSERTED I JOIN DELETED D ON I.Key = D.Key 
      WHERE 
      I.Col <> D.Col) 
... 

o utilizar una variable de tabla para almacenar en caché así evitar el uso repetido de I y D.

SELECT 
    CASE WHEN I.Col1 <> D.Col1 THEN 1 ELSE 0 END AS Col1Diff, 
    CASE WHEN I.Col2 <> D.Col2 THEN 1 ELSE 0 END AS Col2Diff, 
    ... 
FROM 
    INSERTED I JOIN DELETED D ON I.Key = D.Key 

o combinar ideas para poner a prueba todos los cambios en la delantera y salir del gatillo

2

No es que yo sepa. INSERTED y DELETED están ahí por una razón, y la comparación entre ellos parece ser la mejor opción para mí.

IF UPDATE() simplemente le indica si una inserción o actualización se hizo intento, e incluso no reflejan si ese intento fue exitoso o no.

4

La columna fue actualizada. Que el valor anterior y el nuevo valor fueran iguales es solo un detalle. Creo que su única solución es comparar los valores entre pseudo-tablas insertadas y eliminadas.

7

Como han dicho otros, debe utilizar las tablas INSERTED y DELETED.

Esto es lo que he hecho, en lugar de:

IF UPDATE(col1) OR UPDATE(col2)) 
UPDATE table1 
SET col3 = 1 
FROM INSERTED 
WHERE table1.Id = INSERTED.Id 

que he hecho:

IF UPDATE(col1) OR UPDATE(col2)) 
UPDATE table1 
SET col3 = 1 
FROM 
    (SELECT Id, col1, col2 FROM INSERTED 
    EXCEPT 
    SELECT Id, col1, col2 FROM DELETED) AS ALTERED 
WHERE table1.Id = ALTERED.Id 

Usando EXCEPT selecciona las filas distintas en las columnas Estoy interesado no existen en el borrado (o datos originales) tabla (lo que significa que el valor de esas columnas ha cambiado). No sé si esta es la mejor respuesta, pero parece funcionar.

Cuestiones relacionadas