web-dev-qa-db-fra.com

Comment déterminer si quelque chose a changé dans le déclencheur de mise à jour dans t-sql

Comment puis-je déterminer si quelque chose a changé dans le déclencheur UPDATE? Par exemple, j'ai une table nommée person avec une seule colonne NAME qui contient la valeur 'Mike'. Si je cours

UPDATE person SET NAME = 'Mike' 

comment puis-je déterminer dans le déclencheur de mise à jour que rien n'a changé? Je connais l'instruction UPDATE (col), mais je ne veux pas parcourir les colonnes. Existe-t-il un autre moyen d'y parvenir?

23
Marian Zagoruiko

Update (colonne) indique simplement que la colonne a participé à la mise à jour, mais pas que sa valeur a changé. Par exemple,

update Person SET Name = Name

renvoie true dans la mise à jour (nom) même si le nom n'a été modifié dans aucune ligne.

Pour vérifier si les nouvelles valeurs diffèrent des anciennes, vous utiliseriez sauf car except supprimera les lignes de l'ensemble supérieur qui existent dans l'ensemble inférieur. Comme la table des personnes a probablement une clé primaire, il n'y a pas de danger de supprimer l'élément modifié qui a une contrepartie supprimée. Cependant, si vous décidez de changer * à une liste de colonnes intéressantes, assurez-vous d'inclure la clé primaire.

insert into logTable (ID)
select a.ID
from
(
   select * from Inserted
   except
   select * from Deleted
) a

L'avantage supplémentaire est que cela fonctionne également pour les insertions, car Supprimé sera vide et toutes les lignes insérées seront retournées.

40

Se référant à la réponse d'Arion ci-dessus:

Assurez-vous de comparer les enregistrements par leur clé primaire lors de la sélection à partir d'une jointure, car les tables INSERTED et DELETED peuvent contenir plusieurs enregistrements, ce qui, s'il est ignoré, peut entraîner des résultats de requête incorrects et un impact négatif sur les performances de la base de données.

-- Anrion's answer - slightly modified
CREATE TRIGGER UpdatedTriggerName
ON person -- table name
AFTER UPDATE
AS 
IF EXISTS (
    SELECT
        *
    FROM
        INSERTED I
        JOIN
        DELETED D
            -- make sure to compare inserted with (same) deleted person
            ON D.ID = I.ID 
            AND D.NAME <> I.NAME -- only persons with changed name
    )
print 'something'
GO
21
DeMo