Pregunta

Si recibimos una declaración de actualización que no verifica si el valor ha cambiado en la cláusula WHERE, ¿cuáles son las diferentes formas de ignorar esa actualización dentro de un desencadenante?

Sé que podemos hacer una comparación de cada campo individual (manejando el lado de Isnull también), pero donde es una tabla que tiene más de 50 campos, ¿hay una forma más rápida/más fácil de hacerlo?

Nota: Esto podría usarse para reducir IO/ruido en los registros de auditoría, etc.

EJEMPLO

Para una tabla de:

CREATE TABLE myTest
(ID int NOT NULL IDENTITY(1,1), 
 Field1 varchar(10) NULL,
 Field2 varchar(20) NULL)

con un disparador de actualización posterior que contiene:

INSERT INTO myTestAudit (ID, Field1, Field2, DateTimeUpdate)
SELECT ID, Field1, Field2, getDate()
FROM inserted

con valores iniciales:

INSERT INTO myTest (Field1, Field2)
SELECT 'a', 'b' UNION ALL
SELECT 'a', 'c'

Ahora ejecute una actualización:

UPDATE myTest set Field2 = 'b' WHERE Field1 = 'a'
¿Fue útil?

Solución

Para traer filas donde al menos un valor ha cambiado, puede usar

SELECT /*TODO: Column List*/
FROM   INSERTED I
       JOIN DELETED D
         ON I.ID = D.ID
            AND EXISTS (SELECT I.*
                        EXCEPT
                        SELECT D.*)  

Otros consejos

Pon esto como la primera línea en tu gatillo:

-- Exit trigger if no data was actually modified
IF (@@ROWCOUNT  = 0)  return

Hago esto en todos mis desencadenantes de auditoría. Es corto y al grano, definitivamente reduce la E/S desperdiciada.

Actualización: Lo siento, leí mal tu pregunta. Pensé que había preguntado cómo salir del desencadenante si no han cambiado datos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a dba.stackexchange
scroll top