J'utilise Sqlserver express et je ne peux pas faire before updated
déclencheur. Il y a une autre façon de faire ça?
MSSQL ne prend pas en charge les déclencheurs BEFORE
. Le plus proche que vous avez est INSTEAD OF
se déclenche mais leur comportement est différent de celui des déclencheurs BEFORE
dans MySQL.
Vous pouvez en savoir plus à leur sujet ici , et notez que INSTEAD OF
triggers "Spécifie que le déclencheur est exécuté à la place de l'instruction SQL de déclenchement, remplaçant ainsi les actions des instructions de déclenchement." Ainsi, des actions sur la mise à jour peuvent ne pas avoir lieu si le déclencheur n'est pas correctement écrit/géré. Les actions en cascade sont également affectées.
Vous voudrez peut-être plutôt utiliser une approche différente de ce que vous essayez de réaliser.
Il est vrai qu'il n'y a pas de "déclencheurs avant" dans MSSQL. Cependant, vous pouvez toujours suivre les modifications qui ont été apportées à la table, en utilisant les tables "insérées" et "supprimées" ensemble. Lorsqu'une mise à jour provoque le déclenchement du déclencheur, la table "insérée" stocke les nouvelles valeurs et la table "supprimée" stocke les anciennes valeurs. Une fois que vous disposez de ces informations, vous pouvez simuler relativement facilement le comportement "avant le déclenchement".
Je ne peux pas être sûr que cela s'applique à SQL Server Express, mais vous pouvez toujours accéder aux données "avant" même si votre déclencheur se produit APRÈS la mise à jour. Vous devez lire les données de la table supprimée ou insérée qui est créée à la volée lorsque la table est modifiée. C'est essentiellement ce que dit @Stamen, mais j'avais encore besoin d'explorer davantage pour comprendre cette réponse (utile!).
La table supprimée stocke des copies des lignes affectées lors des instructions DELETE et UPDATE. Lors de l'exécution d'une instruction DELETE ou UPDATE, les lignes sont supprimées de la table de déclenchement et transférées vers la table supprimée ...
La table insérée stocke des copies des lignes affectées lors des instructions INSERT et UPDATE. Lors d'une transaction d'insertion ou de mise à jour, de nouvelles lignes sont ajoutées à la fois à la table insérée et à la table de déclenchement ...
Vous pouvez donc créer votre déclencheur pour lire les données de l'une de ces tables, par exemple.
CREATE TRIGGER <TriggerName> ON <TableName>
AFTER UPDATE
AS
BEGIN
INSERT INTO <HistoryTable> ( <columns...>, DateChanged )
SELECT <columns...>, getdate()
FROM deleted;
END;
Mon exemple est basé sur celui ici:
T-SQL ne prend en charge que les déclencheurs AFTER et INSTEAD OF, il ne comporte pas de déclencheur BEFORE, comme dans certains autres SGBDR.
Je pense que vous voudrez utiliser un déclencheur AU LIEU DE.
Tous les déclencheurs "normaux" de SQL Server sont des déclencheurs "APRÈS ...". Il n'y a pas de déclencheurs "AVANT ...".
Pour faire quelque chose avant une mise à jour, consultez INSTEAD OF UPDATE Triggers .
Pour faire un BEFORE UPDATE
dans SQL Server j'utilise une astuce. Je fais une fausse mise à jour de l'enregistrement (UPDATE Table SET Field = Field
), de cette manière, j'obtiens l'image précédente de l'enregistrement.
N'oubliez pas que lorsque vous utilisez un déclencheur à la place, il ne valide pas l'insertion, sauf si vous le lui demandez spécifiquement dans le déclencheur. Au lieu de signifie vraiment faire ceci au lieu de ce que vous faites normalement, donc aucune des actions d'insertion normales ne se produirait.
Exemple complet:
CREATE TRIGGER [dbo].[trig_020_Original_010_010_Gamechanger]
ON [dbo].[T_Original]
AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @Old_Gamechanger int;
DECLARE @New_Gamechanger int;
-- Insert statements for trigger here
SELECT @Old_Gamechanger = Gamechanger from DELETED;
SELECT @New_Gamechanger = Gamechanger from INSERTED;
IF @Old_Gamechanger != @New_Gamechanger
BEGIN
INSERT INTO [dbo].T_History(ChangeDate, Reason, Callcenter_ID, Old_Gamechanger, New_Gamechanger)
SELECT GETDATE(), 'Time for a change', Callcenter_ID, @Old_Gamechanger, @New_Gamechanger
FROM deleted
;
END
END