Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Créer un déclencheur "Au lieu de" dans SQL Server

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 .