Trigger for update

Fermé
houppa - 4 sept. 2018 à 22:19
 SQLpro - 26 sept. 2018 à 14:53
Bonjour,

Je suis débutant en programmation et je cherche comment faire si il y a un changement dans ma table1 alors je veux enregistrer dans une table2 que j'ai créer la date du changement(soit GETDATE()), le nom du champ modifié (soit le nom de la colonne qui a été modifié), l'ancienne et nouvelle valeur

Voici mon code :
CREATE TRIGGER modification ON Table1
FOR UPDATE
AS
BEGIN
DECLARE @idt1 int
SET @idt1 = (SELECT id FROM Table1)


INSERT INTO dbo.Table2
(date_changement, nom_champ_modifie, ancienne_valeur, nouvelle_valeur, id_location)
SELECT GETDATE(), **************, deleted.date_contrat, inserted.date_contrat, @idt1 FROM inserted
INNER JOIN deleted ON inserted.id = deleted.id
RETURN;
END

C'est ou il y a les ********* qui me cause problème...

Merci de votre aide !
A voir également:

2 réponses

Reivax962 Messages postés 3672 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
7 sept. 2018 à 10:54
Bonjour,

Ce n'est pas une information directement accessible, et d'ailleurs rien n'indique qu'il n'y a qu'un seul champ modifié.

Ce que tu peux faire, c'est le repérer manuellement, pour chaque colonne de ta table :
-- Verif Champ1
IF (SELECT CASE WHEN i.Champ1 = d.Champ1 THEN 1 ELSE 0 END FROM inserted i, deleted d) = 0
    INSERT INTO dbo.Table2 (date_changement, nom_champ_modifie, ancienne_valeur, nouvelle_valeur, id_location)
    SELECT GETDATE(), 'Champ1', d.champ1, i.champ1, @idt1 FROM inserted i, deleted d;

-- Verif Champ2
IF (SELECT CASE WHEN i.Champ2 = d.Champ2 THEN 1 ELSE 0 END FROM inserted i, deleted d) = 0
    INSERT INTO dbo.Table2 (date_changement, nom_champ_modifie, ancienne_valeur, nouvelle_valeur, id_location)
    SELECT GETDATE(), 'Champ2', d.champ2, i.champ2, @idt1 FROM inserted i, deleted d;

--Verif Champ3
-- etc...

Attention cependant, j'imagine que tes champs n'ont pas tous le même type, donc un cast en varchar sera sans doute de rigueur sur les champ avant/après.

Ce code a un autre inconvénient, c'est que le trigger devra être mis à jour à chaque fois qu'une colonne est ajoutée / supprimée de la table.

Après, il y a moyen de faire une procédure plus générique en s'appuyant sur les tables systèmes qui contiennent les définitions des colonnes (sys.tables, sys.columns) et en construisant la requête dans un champ varchar() puis en l'exécutant dynamiquement (sp_executesql). Ça permettra de créer une seule boucle, et donc nécessitera moins de maintenance.

Xavier
0
Lisez l'article que j'ai écrit à ce sujet :
https://blog.developpez.com/sqlpro/p8453/langage-sql-norme/historisation_de_l_evolution_des_donnees

Contrairement à ce qui vous a été dit, l'utilisation des tables systèmes n'est pas un bon choix en pratique car ces dernières peuvent évoluer sans préavis dans un Patch ou un CU.

A +
0