sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man kör en utlösare endast när en specifik kolumn uppdateras (SQL-server)

I SQL Server kan du skapa DML-utlösare som exekverar kod endast när en specifik kolumn uppdateras.

Utlösaren aktiveras fortfarande, men du kan testa om en specifik kolumn har uppdaterats eller inte och sedan köra kod endast om den kolumnen har uppdaterats.

Du kan göra detta genom att använda UPDATE() funktion inuti din trigger. Denna funktion accepterar kolumnnamnet som dess argument. Det returnerar ett booleskt värde.

Exempel

Här är tabellen:

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

Och här är triggern:

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 det här exemplet skapar jag en tabell som heter t1 och en trigger som heter trg_t1 .

Jag använder en IF uttalande tillsammans med UPDATE() funktion för att testa om c1 kolumnen uppdaterades.

När triggern körs kommer den bara att exekvera den efterföljande koden om det villkoret är sant.

Avsluta utlösaren

Låt oss infoga en rad, men vi infogar bara ett värde i c1 kolumn.

INSERT INTO t1 (c1) 
VALUES (1);

SELECT * FROM t1;

Resultat:

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

Som väntat aktiverades utlösaren och kolumnen c3 uppdaterades också.

Detta hände för att jag inkluderade INSERT argument i min utlösares definition (dvs. jag angav AFTER INSERT, UPDATE vilket innebär att utlösaren aktiveras när data infogas eller uppdateras). Om jag bara hade angett AFTER UPDATE , det skulle inte ha aktiverats när jag infogade data – det skulle bara aktiveras när jag uppdaterar befintliga data.

Kom ihåg att tabellen definierades med DEFAULT 0 , så c2-kolumnen var som standard noll.

Låt oss nu uppdatera c1 kolumn.

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

SELECT * FROM t1;

Resultat:

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

Återigen, c3 kolumnen uppdaterades tillsammans med c1 .

Låt oss nu göra en uppdatering av c2 kolumn (denna kolumn ingår inte i utlösaren).

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

SELECT * FROM t1;

Resultat:

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

Så den här gången, c2 uppdaterades men c3 var inte. Det beror på att c1 kolumnen uppdaterades inte och vår trigger uppdaterar bara c3 när c1 är uppdaterad.

Samma sak skulle ha hänt om vi hade infogat en rad utan att ange c1 i INSERT uttalande.

Vad händer om jag uppdaterar kolumnen med samma värde?

Om du uppdaterar en kolumn med samma värde visas UPDATE() funktion kommer att returnera sant.

Här är ett exempel.

Vi vet från våra tidigare exempel att c1-kolumnen innehåller värdet 2 .

Låt oss explicit uppdatera den kolumnen med samma värde:1

UPDATE t1 
SET c1 = 2
WHERE id = 1;

SELECT * FROM t1;

Resultat:

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

Så nu c3 har ökat, även om värdet för c1 är fortfarande densamma.

Låt oss göra det igen, men den här gången ställer vi in ​​det på sig självt (dvs. ändra c1 = 1 till c1 = c1 ).

UPDATE t1 
SET c1 = c1
WHERE id = 1;

SELECT * FROM t1;

Resultat:

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

Återigen, c3 har ökat.

Mislyckade uppdateringsförsök

Det är viktigt att notera att UPDATE() funktionen indikerar bara om en INSERT eller UPDATE försök gjordes på en specificerad kolumn i en tabell eller vy. Det kommer fortfarande att returneras sant om försöket misslyckades.


  1. Hur SQLite Count() fungerar

  2. Hur skickar man XML från C# till en lagrad procedur i SQL Server 2008?

  3. Hur väljer man endast datum från ett DATETIME-fält i MySQL?

  4. Skapa en fråga i SQL Server 2017