sql >> Database teknologi >  >> RDS >> Sqlserver

Sådan udføres kun en trigger, når en specifik kolonne er opdateret (SQL-server)

I SQL Server kan du oprette DML-triggere, der kun udfører kode, når en specifik kolonne opdateres.

Udløseren udløses stadig, men du kan teste, om en specifik kolonne blev opdateret eller ej, og derefter kun køre kode, hvis denne kolonne blev opdateret.

Du kan gøre dette ved at bruge UPDATE() funktion inde i din trigger. Denne funktion accepterer kolonnenavnet som dets argument. Det returnerer en boolean.

Eksempel

Her er tabellen:

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

Og her er udløseren:

CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE (c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;

I dette eksempel opretter jeg en tabel kaldet t1 og en trigger kaldet trg_t1 .

Jeg bruger en IF sætning sammen med UPDATE() funktion til at teste om c1 kolonne blev opdateret.

Når triggeren kører, vil den kun udføre den efterfølgende kode, hvis denne betingelse er sand.

Udløs triggeren

Lad os indsætte en række, men vi indsætter kun en værdi i c1 kolonne.

INSERT INTO t1 (c1) 
VALUES (1);

SELECT * FROM t1;

Resultat:

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

Som forventet udløste triggeren, og kolonnen c3 blev også opdateret.

Dette skete, fordi jeg inkluderede INSERT argument i min triggers definition (dvs. jeg specificerede AFTER INSERT, UPDATE hvilket betyder, at udløseren udløses, hver gang data indsættes eller opdateres). Hvis jeg kun havde angivet AFTER UPDATE , ville det ikke have udløst, når jeg indsatte data – det ville kun udløses, når jeg opdaterer eksisterende data.

Husk at tabellen blev defineret med DEFAULT 0 , så c2-kolonnen var som standard nul.

Lad os nu opdatere c1 kolonne.

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

SELECT * FROM t1;

Resultat:

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

Igen, c3 kolonne blev opdateret sammen med c1 .

Lad os nu lave en opdatering til c2 kolonne (denne kolonne er ikke inkluderet i triggeren).

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

SELECT * FROM t1;

Resultat:

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

Så denne gang, c2 blev opdateret, men c3 var det ikke. Det er fordi c1 kolonnen blev ikke opdateret, og vores trigger opdaterer kun c3 når c1 er opdateret.

Det samme ville være sket, hvis vi havde indsat en række uden at angive c1 i INSERT erklæring.

Hvad hvis jeg opdaterer kolonnen med samme værdi?

Hvis du opdaterer en kolonne med samme værdi, vises UPDATE() funktion vil returnere sand.

Her er et eksempel.

Vi ved fra vores tidligere eksempler, at c1-kolonnen indeholder en værdi på 2 .

Lad os eksplicit opdatere den kolonne med den samme værdi:1

UPDATE t1 
SET c1 = 2
WHERE id = 1;

SELECT * FROM t1;

Resultat:

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

Så nu c3 er steget, selvom værdien for c1 er stadig den samme.

Lad os gøre det igen, men denne gang indstilles det til sig selv (dvs. ændre c1 = 1 til c1 = c1 ).

UPDATE t1 
SET c1 = c1
WHERE id = 1;

SELECT * FROM t1;

Resultat:

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

Igen, c3 er steget.

Mislykkede opdateringsforsøg

Det er vigtigt at bemærke, at UPDATE() funktion angiver blot, om en INSERT eller UPDATE forsøg blev lavet på en specificeret kolonne i en tabel eller visning. Det vil stadig returnere sandt, hvis forsøget var mislykket.


  1. Husk RAC-forekomster i Perf Tools

  2. PostgreSQL:Deaktiver midlertidigt forbindelser

  3. Gør postgres datorepræsentation til ISO 8601-streng

  4. hvor 1=1 udsagn