Bonjour
Afin de pouvoir gérer l'historique de ma base à chaque changement, j'ai pensé que des triggers pouvaient m'aider.
C'est mon premier contact avec ces bestioles là, et autant dire tout de suite que je suis pas une star en T-SQL
Pour schématiser, voici le mécanisme que j'aimerais mettre en oeuvre :
2 tables, une parent et une enfant, qui ont chacune une colonne de données (c'est pour simplifier), et l'horodatage.
Lorsque ValeurParent change, voici ce que j'ai voulu implémenter dans mon trigger :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 CREATE TABLE dbo.Parent ( idParent uniqueidentifier NOT NULL, ValeurParent int NOT NULL, DateDebut datetime NOT NULL, DateFin datetime NULL ) ON [PRIMARY] GO ALTER TABLE dbo.Parent ADD CONSTRAINT DF_Parent_DateDebut DEFAULT getdate() FOR DateDebut GO ALTER TABLE dbo.Parent ADD CONSTRAINT PK_Parent PRIMARY KEY CLUSTERED ( idParent ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO ALTER TABLE dbo.Parent SET (LOCK_ESCALATION = TABLE) GO CREATE TABLE dbo.Enfant ( idEnfant uniqueidentifier NOT NULL, idParent_FK uniqueidentifier NOT NULL, ValeurEnfant int NOT NULL, DateFin datetime NULL, DateDebut datetime NOT NULL ) ON [PRIMARY] GO ALTER TABLE dbo.Enfant ADD CONSTRAINT DF_Enfant_DateDebut DEFAULT getdate() FOR DateDebut GO ALTER TABLE dbo.Enfant ADD CONSTRAINT PK_Enfant PRIMARY KEY CLUSTERED ( idEnfant ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO ALTER TABLE dbo.Enfant ADD CONSTRAINT FK_Enfant_Parent FOREIGN KEY ( idParent_FK ) REFERENCES dbo.Parent ( idParent ) ON UPDATE NO ACTION ON DELETE NO ACTION GO ALTER TABLE dbo.Enfant ADD CONSTRAINT FK_Enfant_PetitEnfant FOREIGN KEY ( idEnfant ) REFERENCES dbo.PetitEnfant ( idPetitEnfant ) ON UPDATE NO ACTION ON DELETE NO ACTION GO
Jusque là, tout va bien.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 DECLARE @NewID as uniqueidentifier SET @NewID = NewID() -- On remet les anciennes valeurs dans la ligne mise à jour UPDATE Parent SET DateFin = GETDATE(), ValeurParent = Deleted.ValeurParent FROM Parent, Deleted WHERE Parent.idParent = Deleted.idParent -- On crée la ligne avec les valeurs à jour INSERT INTO Parent (idParent, ValeurParent, DateDebut) SELECT @NewID, Inserted.ValeurParent, GETDATE() FROM Inserted -- Et on pousse la mise à jour vers les enfants UPDATE Enfant SET idParent_fk = @NewID FROM Enfant, Deleted WHERE Enfant.idParent_FK = Deleted.idParent AND Enfant.DateEnd IS NULL
Mais du coup, comme le parent a changé, il faut changer les enfants aussi.
Et donc, un autre Trigger, sur la table enfant cette fois.
Et ca marche très bien... Tant qu'il y a qu'un enfant à modifier !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 DECLARE @NewID as uniqueidentifier SET @NewID = NewID() -- On remet les anciennes valeurs dans la ligne mise à jour UPDATE Enfant SET DateFin = GETDATE(), ValeurEnfant = Deleted.ValeurEnfant, idParent_FK = Deleted.idParent_FK FROM Enfant, Deleted WHERE Enfant.idEnfant = Deleted.idEnfant -- On crée la ligne avec les valeurs à jour INSERT INTO Enfant (idEnfant, idParent_FK, ValeurEnfant, DateDebut) SELECT @NewID, Inserted.idParent_FK, Inserted.ValeurParent, GETDATE() FROM Inserted
J'ai lu qu'il fallait traiter les triggers de manière ensembliste, et ne pas utiliser de variable locale dedans.
Le problème c'est le NewID() de l'enfant, je ne vois pas comment créer un nouveau GUID pour chaque ligne de la table Enfant qui va être recréée depuis le Trigger.
Merci pour votre aide
Partager