web-dev-qa-db-fra.com

IF UPDATE () dans le déclencheur du serveur SQL

S'il y a:

IF UPDATE (col1)

... dans le déclencheur du serveur SQL sur une table, renvoie-t-il vrai uniquement si col1 a été modifié ou mis à jour?

J'ai une requête de mise à jour régulière comme

UPDATE table-name 
   SET col1 = 'x', 
       col2 =  'y' 
 WHERE id = 999

Maintenant, quelle est ma préoccupation si le "col1" était "x" auparavant, puis de nouveau nous l'avons mis à jour en "x" Est-ce que IF UPDATE ("col1") trigger retournera True ou pas?

Je suis confronté à ce problème car ma requête de sauvegarde est générique pour toutes les colonnes, mais lorsque j'ajoute cette condition, elle renvoie True même si elle n'est pas modifiée ... Je me demande donc quoi faire dans ce cas si je souhaite ajouter une condition comme celle-ci. ?

28
Jason M

Il renvoie true si une colonne a été mise à jour. Une mise à jour signifie que la requête a défini la valeur de la colonne. Que la valeur précédente soit la même que la nouvelle valeur est en grande partie hors de propos.

UPDATE table SET col = col

c'est une mise à jour.

UPDATE table SET col = 99

quand le col avait déjà la valeur 99, c'est aussi une mise à jour.

43
Remus Rusanu

Dans le déclencheur, vous avez accès à deux tables internes pouvant vous aider. Le tableau 'inséré' inclut la nouvelle version de chaque ligne affectée, le tableau 'supprimé' inclut la version d'origine de chaque ligne. Vous pouvez comparer les valeurs de ces tables pour voir si la valeur de votre champ a réellement été modifiée.

10
Ray

Ce que vous faites est de rechercher des valeurs différentes dans les tables insérées et supprimées plutôt que d'utiliser updated () (N'oubliez pas de prendre en compte les valeurs NULL). Ou vous pouvez arrêter de faire des mises à jour inutiles.

2
HLGEM

Voici un moyen rapide d’analyser les lignes pour voir si TOUTE colonne a été modifiée avant de décider d’exécuter le contenu d’un déclencheur. Cela peut être utile par exemple lorsque vous voulez écrire un enregistrement d’historique, mais vous ne voulez pas le faire si rien n’a vraiment changé.

Nous l'utilisons tout le temps dans les processus d'importation ETL où nous pouvons réimporter des données, mais si rien ne change vraiment dans le fichier source, nous ne voulons pas créer un nouvel enregistrement d'historique.

CREATE TRIGGER [dbo].[TR_my_table_create_history]
ON [dbo].[my_table] FOR UPDATE AS

BEGIN

    --
    -- Insert the old data row if any column data changed
    --
    INSERT INTO [my_table_history]
    SELECT  d.*
    FROM    deleted d
    INNER JOIN inserted i ON i.[id] = d.[id]
    --
    -- Use INTERSECT to see if anything REALLY changed
    --
    WHERE   NOT EXISTS( SELECT i.* INTERSECT SELECT d.* )

END

Notez que ce déclencheur particulier suppose que votre table source (celle qui déclenche le déclencheur) et la table d'historique ont des dispositions de colonnes identiques.

2
Bruce Pierson

Pour raccourcir le cas "Aucune mise à jour réelle", vous devez également vérifier au début si votre requête a affecté des lignes:

set nocount on; -- this must be the first statement!
if not exists (select 1 from inserted) and not exists (select 1 from deleted)
  return;
1
Oliver
cREATE TRIGGER boo  ON status2 FOR UPDATE AS 
IF UPDATE (id)
BEGIN
SELECT 'DETECT'; 
END;

UPDATE status2 SET name = 'K' WHERE name= 'T' --no action 
UPDATE status2 SET name = 'T' ,id= 8 WHERE name= 'K' --detect
1
zloctb
SET NOCOUNT ON;

    declare @countTemp int
    select @countTemp = Count (*) from (
    select City,PostCode,Street,CountryId,Address1 from Deleted
    union
    select City,PostCode,Street,CountryId,Address1 from Inserted
    ) tempTable

    IF ( @countTemp > 1 )

Begin

-- Your Code goes Here
End

-- if any of these  "City,PostCode,Street,CountryId,Address1" got updated then trigger

-- will  work in " IF ( @countTemp > 1 ) " Code)
0
Shyam Sharma