sql >> Database >  >> RDS >> Sqlserver

Maak een "in plaats van" trigger in SQL Server

Wanneer u een trigger in SQL Server maakt, hebt u de mogelijkheid om deze te activeren in combinatie met de trigger-instructie (d.w.z. de SQL-instructie die de trigger heeft geactiveerd), of deze in plaats daarvan te activeren van die verklaring.

Om de trigger in plaats daarvan te activeren van de triggering-instructie, gebruik INSTEAD OF argument.

Dit in tegenstelling tot het gebruik van de FOR of AFTER argumenten. Wanneer u deze argumenten gebruikt, wordt de trigger alleen geactiveerd wanneer alle bewerkingen die zijn opgegeven in de activerende SQL-instructie met succes zijn gestart.

Voorbeeld

Maak een voorbeeldtabel:

CREATE TABLE t1 (
    id int IDENTITY(1,1) NOT NULL,
    c1 int DEFAULT 0,
    c2 int DEFAULT 0,
    c3 int DEFAULT 0
);

Maak de trigger:

CREATE TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);

Een voorbeeldrij invoegen:

INSERT INTO t1 (c1, c2, c3) 
VALUES (1, 1, 1);

SELECT * FROM t1;

Dit is wat we tot nu toe hebben:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 1    |
+------+------+------+------+

Laten we nu een UPDATE uitvoeren statement tegen de tafel (hierdoor wordt de trigger geactiveerd).

UPDATE t1 
SET c1 = c1 + 1
WHERE id = 1;

SELECT * FROM t1;

Resultaat:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 2    |
+------+------+------+------+

Zoals verwacht, de UPDATE instructie in de triggering-instructie is vervangen door die in de trigger.

Mijn trigger specificeerde dat elke keer dat er een poging tot update van de tabel is, de c3 . moet worden bijgewerkt kolom in plaats daarvan.

Alleen uitvoeren wanneer een specifieke kolom is bijgewerkt

U kunt ook de UPDATE() . gebruiken functie om code op te geven die alleen moet worden uitgevoerd wanneer een opgegeven kolom wordt bijgewerkt.

We kunnen onze trigger bijvoorbeeld als volgt wijzigen:

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;

Voer nu de vorige UPDATE . uit verklaring nogmaals:

UPDATE t1 
SET c1 = c1 + 1
WHERE id = 1;

SELECT * FROM t1;

Resultaat:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 3    |
+------+------+------+------+

Nogmaals, de c3 kolom wordt verhoogd.

Maar laten we nu proberen de c2 . bij te werken kolom:

UPDATE t1 
SET c2 = c2 + 1
WHERE id = 1;

SELECT * FROM t1;

Resultaat:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 3    |
+------+------+------+------+

Er verandert niets. De c3 kolom blijft hetzelfde.

Zelfs niet de c2 kolom wordt bijgewerkt. Dit komt omdat de trigger nog steeds wordt uitgevoerd in plaats van de trigger-instructie.

Trigger uitvoeren in plaats van VERWIJDEREN

We kunnen de trigger wijzigen zodat deze wordt uitgevoerd in plaats van een DELETE verklaringen.

ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);

Laten we nu proberen alle rijen te verwijderen en vervolgens alle rijen uit de tabel te selecteren.

DELETE FROM t1;

SELECT * FROM t1;

Resultaat:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 4    |
+------+------+------+------+

Merk op dat om deze trigger correct te laten werken, ik de deleted . moest opvragen tabel in mijn trigger (in tegenstelling tot de inserted tabel in de vorige voorbeelden).

Deze twee tabellen worden gemaakt en beheerd door SQL Server.

De deleted tabel slaat kopieën op van de betrokken rijen tijdens DELETE en UPDATE verklaringen. Tijdens het uitvoeren van een DELETE of UPDATE statement, worden rijen verwijderd uit de triggertabel en overgebracht naar de verwijderde tabel.

De inserted tabel slaat kopieën op van de betrokken rijen tijdens INSERT en UPDATE verklaringen. Tijdens een invoeg- of bijwerktransactie worden nieuwe rijen toegevoegd aan zowel de ingevoegde tabel als de triggertabel. De rijen in de ingevoegde tabel zijn kopieën van de nieuwe rijen in de triggertabel.

Enkele beperkingen om in gedachten te houden

U kunt maximaal één INSTEAD OF trigger per INSERT , UPDATE , of DELETE verklaring op een tafel of uitzicht.

U kunt INSTEAD OF . niet definiëren triggers op bij te werken weergaven die gebruik maken van WITH CHECK OPTION .


  1. Asynchrone replicatie instellen tussen MariaDB Galera-clusters

  2. Hoe WEEK() werkt in MariaDB

  3. MySQL-query GROEP PER dag / maand / jaar

  4. Hoe MaxScale voor MariaDB te installeren en configureren