Si UPDATE() dans SQL server trigger
S'il y a:
IF UPDATE (col1)
... dans le déclencheur SQL server sur une table, renvoie-t-il true seulement 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
ce qui me préoccupe, c'est que si la "col1" était 'x' auparavant, nous l'avons à nouveau mise à jour en 'x'
serait -IF UPDATE ("col1")
déclencher retourner Vrai ou pas?
je suis confronté à ce problème car ma requête de sauvegarde est générique pour toutes les colonnes, mais quand j'ajoute cette condition il retourne C'est vrai même si ça n'a pas changé...alors je me demande ce que je dois faire dans ce cas si je veux ajouter une condition comme ça?
8 réponses
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. Si la valeur précédente était la même que la nouvelle valeur est largement irelevant.
UPDATE table SET col = col
c'est une mise à jour.
UPDATE table SET col = 99
quand la CLO avait déjà la valeur 99 c'est aussi une mise à jour.
dans le déclencheur, vous avez accès à deux tables internes qui peuvent aider. Le "insérée" table comprend la nouvelle version de chaque ligne, Le "supprimer" tableau comprend la version originale de chaque ligne. Vous pouvez comparer les valeurs dans ces tableaux pour voir si votre valeur de champ a été réellement changée.
ce que vous faites est de vérifier les différentes valeurs dans les tableaux insérés et supprimés plutôt que d'utiliser updated() (N'oubliez pas de tenir compte des nulls). Ou vous pourriez arrêter de faire des mises à jour inutiles.
Voici un moyen rapide pour numériser les lignes pour voir si une colonne changé avant de décider d'exécuter le contenu d'un déclencheur. Cela peut être utile par exemple quand vous voulez écrire un enregistrement d'histoire, mais vous ne voulez pas le faire si rien n'a vraiment changé.
nous utilisons cela tout le temps dans les processus d'importation ETL où nous pouvons réimporter des données mais si rien n'a vraiment changé dans le fichier source, nous ne voulons pas créer un nouvel enregistrement 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 cette trigger suppose que votre table source (celle qui déclenche le trigger) et la table history ont des dispositions de colonne identiques.
raccourci "Pas de mise à jour" cas, vous devez également vérifier au début si votre requête touché toutes les 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;
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
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)
Cela a fonctionné pour moi
DECLARE @LongDescDirty bit = 0
Declare @old varchar(4000) = (SELECT LongDescription from deleted)
Declare @new varchar(4000) = (SELECT LongDescription from inserted)
if (@old <> @new)
BEGIN
SET @LongDescDirty = 1
END
Update table
Set LongDescUpdated = @LongDescUpdated
.....