Trigger - Savoir si un enregistrement a VRAIMENT été modifié
2 réponses
HervéR
Bonjour,
Je veux faire quelque chose de banal : insérer dans une table B les données
d'une table A avant que celles-ci soient modifiées.
J'ai donc fait un trigger ON UPDATE sur A.
Je voudrais éviter que des lignes soient insérées dans B quand A n'a pas été
modifié.
Je voudrais d'avoir à vérifier champ par champ ce qui a bougé.
Avez-vous une idée ?
Pour info, je connais un peu les fonctions If Update( col ) et
COLUMNS_UPDATED().
J'ai testé avec Udapte() : si on fait
Update A
set Champ1 = Champ1
where Id = x
Le trigger considère que la ligne a été modifiée, même en écrivant dans le
trigger « If Update (Champ1)... »
Je vois bien un truc lourdingue du genre : faire une union entre les tables
inserted et deleted, union qui ne fera pas ressortir les lignes
identiques... mais bon !
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Fred BROUARD
Il suffit d'utiliser les pseudo tables inserted et deleted pour voir le différentiel.
Du genre :
IF UPDATE(COLX) BEGIN
IF EXISTS(SELECT * FROM inserted i INNER JOIN deleted d ON i.clef = d.clef WHERE i.COLX <> d.COLX OR (i.COLX IS NULL AND d.COLX IS NOT NULL) OR (i.COLX IS NOT NULL AND d.COLX IS NULL)) BEGIN ... traitement END END
A +
-- Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com Audit, conseil, expertise, formation, modélisation, tuning, optimisation ********************* http://www.datasapiens.com ***********************
HervéR a écrit:
Bonjour,
Je veux faire quelque chose de banal : insérer dans une table B les données d'une table A avant que celles-ci soient modifiées. J'ai donc fait un trigger ON UPDATE sur A. Je voudrais éviter que des lignes soient insérées dans B quand A n'a pas été modifié. Je voudrais d'avoir à vérifier champ par champ ce qui a bougé. Avez-vous une idée ?
Pour info, je connais un peu les fonctions If Update( col ) et COLUMNS_UPDATED(). J'ai testé avec Udapte() : si on fait Update A set Champ1 = Champ1 where Id = x Le trigger considère que la ligne a été modifiée, même en écrivant dans le trigger « If Update (Champ1)... »
Je vois bien un truc lourdingue du genre : faire une union entre les tables inserted et deleted, union qui ne fera pas ressortir les lignes identiques... mais bon !
Il suffit d'utiliser les pseudo tables inserted et deleted pour voir le
différentiel.
Du genre :
IF UPDATE(COLX)
BEGIN
IF EXISTS(SELECT *
FROM inserted i
INNER JOIN deleted d
ON i.clef = d.clef
WHERE i.COLX <> d.COLX
OR (i.COLX IS NULL AND d.COLX IS NOT NULL)
OR (i.COLX IS NOT NULL AND d.COLX IS NULL))
BEGIN
... traitement
END
END
A +
--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
********************* http://www.datasapiens.com ***********************
HervéR a écrit:
Bonjour,
Je veux faire quelque chose de banal : insérer dans une table B les données
d'une table A avant que celles-ci soient modifiées.
J'ai donc fait un trigger ON UPDATE sur A.
Je voudrais éviter que des lignes soient insérées dans B quand A n'a pas été
modifié.
Je voudrais d'avoir à vérifier champ par champ ce qui a bougé.
Avez-vous une idée ?
Pour info, je connais un peu les fonctions If Update( col ) et
COLUMNS_UPDATED().
J'ai testé avec Udapte() : si on fait
Update A
set Champ1 = Champ1
where Id = x
Le trigger considère que la ligne a été modifiée, même en écrivant dans le
trigger « If Update (Champ1)... »
Je vois bien un truc lourdingue du genre : faire une union entre les tables
inserted et deleted, union qui ne fera pas ressortir les lignes
identiques... mais bon !
Il suffit d'utiliser les pseudo tables inserted et deleted pour voir le différentiel.
Du genre :
IF UPDATE(COLX) BEGIN
IF EXISTS(SELECT * FROM inserted i INNER JOIN deleted d ON i.clef = d.clef WHERE i.COLX <> d.COLX OR (i.COLX IS NULL AND d.COLX IS NOT NULL) OR (i.COLX IS NOT NULL AND d.COLX IS NULL)) BEGIN ... traitement END END
A +
-- Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com Audit, conseil, expertise, formation, modélisation, tuning, optimisation ********************* http://www.datasapiens.com ***********************
HervéR a écrit:
Bonjour,
Je veux faire quelque chose de banal : insérer dans une table B les données d'une table A avant que celles-ci soient modifiées. J'ai donc fait un trigger ON UPDATE sur A. Je voudrais éviter que des lignes soient insérées dans B quand A n'a pas été modifié. Je voudrais d'avoir à vérifier champ par champ ce qui a bougé. Avez-vous une idée ?
Pour info, je connais un peu les fonctions If Update( col ) et COLUMNS_UPDATED(). J'ai testé avec Udapte() : si on fait Update A set Champ1 = Champ1 where Id = x Le trigger considère que la ligne a été modifiée, même en écrivant dans le trigger « If Update (Champ1)... »
Je vois bien un truc lourdingue du genre : faire une union entre les tables inserted et deleted, union qui ne fera pas ressortir les lignes identiques... mais bon !
HervéR
Merci pour ta réponse... que je redoutais ! Tu donnes l'exemple
WHERE i.COLX <> d.COLX OR (i.COLX IS NULL AND d.COLX IS NOT NULL) OR (i.COLX IS NOT NULL AND d.COLX IS NULL))
qui vérifie si UNE colonne a bougé. Ça va être très (très très) lourd de le faire pour chaque colonne !
Rien n'est prévu nativement, du genre « If Dirty » ? Par ailleurs, que penses-tu de mon idée de l'UNION. Depuis mon post initial, je l'ai codée : -------- CREATE TRIGGER... FOR UPDATE AS ... select * into #INSuDEL from inserted union select * from deleted INSERT MaTableDeLog ( Date_Modif, User_Modif, Type_Modif, [liste des champs] ) select @TheDate, @TheUser, 'U', [liste des champs] from Deleted where itr_id in (select itr_id from #INSuDEL group by itr_id having count(*) > 1 ) drop table #INSuDEL
-------- Ça a l'air de bien marcher, mais n'est pas trop lourd ?
"Fred BROUARD" a écrit dans le message de news:
Il suffit d'utiliser les pseudo tables inserted et deleted pour voir le différentiel.
Du genre :
IF UPDATE(COLX) BEGIN
IF EXISTS(SELECT * FROM inserted i INNER JOIN deleted d ON i.clef = d.clef WHERE i.COLX <> d.COLX OR (i.COLX IS NULL AND d.COLX IS NOT NULL) OR (i.COLX IS NOT NULL AND d.COLX IS NULL)) BEGIN ... traitement END END
A +
-- Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com Audit, conseil, expertise, formation, modélisation, tuning, optimisation ********************* http://www.datasapiens.com ***********************
HervéR a écrit:
Bonjour,
Je veux faire quelque chose de banal : insérer dans une table B les données d'une table A avant que celles-ci soient modifiées. J'ai donc fait un trigger ON UPDATE sur A. Je voudrais éviter que des lignes soient insérées dans B quand A n'a pas été modifié. Je voudrais d'avoir à vérifier champ par champ ce qui a bougé. Avez-vous une idée ?
Pour info, je connais un peu les fonctions If Update( col ) et COLUMNS_UPDATED(). J'ai testé avec Udapte() : si on fait Update A set Champ1 = Champ1 where Id = x Le trigger considère que la ligne a été modifiée, même en écrivant dans le trigger « If Update (Champ1)... »
Je vois bien un truc lourdingue du genre : faire une union entre les tables inserted et deleted, union qui ne fera pas ressortir les lignes identiques... mais bon !
Merci pour ta réponse... que je redoutais !
Tu donnes l'exemple
WHERE i.COLX <> d.COLX
OR (i.COLX IS NULL AND d.COLX IS NOT NULL)
OR (i.COLX IS NOT NULL AND d.COLX IS NULL))
qui vérifie si UNE colonne a bougé. Ça va être très (très très) lourd de le
faire pour chaque colonne !
Rien n'est prévu nativement, du genre « If Dirty » ?
Par ailleurs, que penses-tu de mon idée de l'UNION.
Depuis mon post initial, je l'ai codée :
--------
CREATE TRIGGER...
FOR UPDATE
AS
...
select * into #INSuDEL from inserted union select * from deleted
INSERT MaTableDeLog (
Date_Modif, User_Modif, Type_Modif,
[liste des champs]
)
select
@TheDate, @TheUser, 'U',
[liste des champs]
from Deleted
where itr_id in (select itr_id from #INSuDEL group by itr_id having count(*)
> 1 )
drop table #INSuDEL
--------
Ça a l'air de bien marcher, mais n'est pas trop lourd ?
"Fred BROUARD" <brouardf@club-internet.fr> a écrit dans le message de news:
eQuTV3qEGHA.3384@TK2MSFTNGP12.phx.gbl...
Il suffit d'utiliser les pseudo tables inserted et deleted pour voir le
différentiel.
Du genre :
IF UPDATE(COLX)
BEGIN
IF EXISTS(SELECT *
FROM inserted i
INNER JOIN deleted d
ON i.clef = d.clef
WHERE i.COLX <> d.COLX
OR (i.COLX IS NULL AND d.COLX IS NOT NULL)
OR (i.COLX IS NOT NULL AND d.COLX IS NULL))
BEGIN
... traitement
END
END
A +
--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
********************* http://www.datasapiens.com ***********************
HervéR a écrit:
Bonjour,
Je veux faire quelque chose de banal : insérer dans une table B les
données d'une table A avant que celles-ci soient modifiées.
J'ai donc fait un trigger ON UPDATE sur A.
Je voudrais éviter que des lignes soient insérées dans B quand A n'a pas
été modifié.
Je voudrais d'avoir à vérifier champ par champ ce qui a bougé.
Avez-vous une idée ?
Pour info, je connais un peu les fonctions If Update( col ) et
COLUMNS_UPDATED().
J'ai testé avec Udapte() : si on fait
Update A
set Champ1 = Champ1
where Id = x
Le trigger considère que la ligne a été modifiée, même en écrivant dans
le trigger « If Update (Champ1)... »
Je vois bien un truc lourdingue du genre : faire une union entre les
tables inserted et deleted, union qui ne fera pas ressortir les lignes
identiques... mais bon !
Merci pour ta réponse... que je redoutais ! Tu donnes l'exemple
WHERE i.COLX <> d.COLX OR (i.COLX IS NULL AND d.COLX IS NOT NULL) OR (i.COLX IS NOT NULL AND d.COLX IS NULL))
qui vérifie si UNE colonne a bougé. Ça va être très (très très) lourd de le faire pour chaque colonne !
Rien n'est prévu nativement, du genre « If Dirty » ? Par ailleurs, que penses-tu de mon idée de l'UNION. Depuis mon post initial, je l'ai codée : -------- CREATE TRIGGER... FOR UPDATE AS ... select * into #INSuDEL from inserted union select * from deleted INSERT MaTableDeLog ( Date_Modif, User_Modif, Type_Modif, [liste des champs] ) select @TheDate, @TheUser, 'U', [liste des champs] from Deleted where itr_id in (select itr_id from #INSuDEL group by itr_id having count(*) > 1 ) drop table #INSuDEL
-------- Ça a l'air de bien marcher, mais n'est pas trop lourd ?
"Fred BROUARD" a écrit dans le message de news:
Il suffit d'utiliser les pseudo tables inserted et deleted pour voir le différentiel.
Du genre :
IF UPDATE(COLX) BEGIN
IF EXISTS(SELECT * FROM inserted i INNER JOIN deleted d ON i.clef = d.clef WHERE i.COLX <> d.COLX OR (i.COLX IS NULL AND d.COLX IS NOT NULL) OR (i.COLX IS NOT NULL AND d.COLX IS NULL)) BEGIN ... traitement END END
A +
-- Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com Audit, conseil, expertise, formation, modélisation, tuning, optimisation ********************* http://www.datasapiens.com ***********************
HervéR a écrit:
Bonjour,
Je veux faire quelque chose de banal : insérer dans une table B les données d'une table A avant que celles-ci soient modifiées. J'ai donc fait un trigger ON UPDATE sur A. Je voudrais éviter que des lignes soient insérées dans B quand A n'a pas été modifié. Je voudrais d'avoir à vérifier champ par champ ce qui a bougé. Avez-vous une idée ?
Pour info, je connais un peu les fonctions If Update( col ) et COLUMNS_UPDATED(). J'ai testé avec Udapte() : si on fait Update A set Champ1 = Champ1 where Id = x Le trigger considère que la ligne a été modifiée, même en écrivant dans le trigger « If Update (Champ1)... »
Je vois bien un truc lourdingue du genre : faire une union entre les tables inserted et deleted, union qui ne fera pas ressortir les lignes identiques... mais bon !