Lorsque vous créez un déclencheur dans SQL Server, vous avez la possibilité de le déclencher en conjonction avec l'instruction de déclenchement (c'est-à-dire l'instruction SQL qui a déclenché le déclencheur), ou de le déclencher à la place de cette déclaration.
Pour déclencher la gâchette à la place de l'instruction de déclenchement, utilisez INSTEAD OF
arguments.
Ceci est en contraste avec l'utilisation du FOR
ou AFTER
arguments. Lorsque vous utilisez ces arguments, le déclencheur ne se déclenche que lorsque toutes les opérations spécifiées dans l'instruction SQL de déclenchement ont été lancées avec succès.
Exemple
Créez un exemple de tableau :
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
Créez le déclencheur :
CREATE TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);
Insérez un exemple de ligne :
INSERT INTO t1 (c1, c2, c3)
VALUES (1, 1, 1);
SELECT * FROM t1;
Voici ce que nous avons jusqu'à présent :
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 1 | +------+------+------+------+
Exécutons maintenant une UPDATE
déclaration contre la table (cela déclenchera le déclencheur).
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Résultat :
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 2 | +------+------+------+------+
Comme prévu, le UPDATE
L'instruction de l'instruction de déclenchement a été remplacée par celle du déclencheur.
Mon déclencheur a spécifié que chaque fois qu'il y a une tentative de mise à jour de la table, mettez à jour le c3
colonne à la place.
Exécuter uniquement lorsqu'une colonne spécifique est mise à jour
Vous pouvez également utiliser le UPDATE()
fonction pour spécifier le code à exécuter uniquement lorsqu'une colonne spécifiée est mise à jour.
Par exemple, nous pourrions modifier notre déclencheur comme suit :
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
IF ( UPDATE(c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
Exécutez maintenant le précédent UPDATE
déclaration à nouveau :
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Résultat :
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Encore une fois, le c3
colonne est incrémentée.
Mais essayons maintenant de mettre à jour le c2
colonne :
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Résultat :
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Rien ne change. Le c3
colonne reste la même.
Pas même le c2
colonne est mise à jour. En effet, le déclencheur s'exécute toujours à la place de l'instruction de déclenchement.
Exécuter le déclencheur au lieu de SUPPRIMER
Nous pouvons modifier le déclencheur pour qu'il s'exécute à la place de tout DELETE
déclarations.
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);
Essayons maintenant de supprimer toutes les lignes, puis de sélectionner toutes les lignes du tableau.
DELETE FROM t1;
SELECT * FROM t1;
Résultat :
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 4 | +------+------+------+------+
Notez que pour que ce déclencheur fonctionne correctement, j'ai dû interroger le deleted
table dans mon déclencheur (par opposition au inserted
table dans les exemples précédents).
Ces deux tables sont créées et gérées par SQL Server.
Le deleted
table stocke des copies des lignes affectées pendant DELETE
et UPDATE
déclarations. Lors de l'exécution d'un DELETE
ou UPDATE
, les lignes sont supprimées de la table de déclenchement et transférées vers la table supprimée.
Le inserted
table stocke des copies des lignes affectées pendant INSERT
et UPDATE
déclarations. 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. Les lignes de la table insérée sont des copies des nouvelles lignes de la table de déclenchement.
Quelques restrictions à garder à l'esprit
Vous pouvez définir au maximum un INSTEAD OF
déclencheur par INSERT
, UPDATE
, ou DELETE
déclaration sur une table ou une vue.
Vous ne pouvez pas définir INSTEAD OF
déclencheurs sur les vues pouvant être mises à jour qui utilisent WITH CHECK OPTION
.