sql >> Databáze >  >> RDS >> Sqlserver

Jak spustit spouštěč pouze při aktualizaci konkrétního sloupce (SQL Server)

Na serveru SQL Server můžete vytvořit spouštěče DML, které spouštějí kód pouze při aktualizaci určitého sloupce.

Spouštěč se stále spouští, ale můžete otestovat, zda byl konkrétní sloupec aktualizován či nikoli, a poté spustit kód pouze v případě, že byl tento sloupec aktualizován.

Můžete to provést pomocí UPDATE() funkce uvnitř vaší spouště. Tato funkce přijímá jako argument název sloupce. Vrací boolean.

Příklad

Zde je tabulka:

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

A tady je spouštěč:

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;

V tomto příkladu vytvořím tabulku s názvem t1 a spouštěč nazvaný trg_t1 .

Používám IF spolu s UPDATE() funkce pro testování, zda c1 sloupec byl aktualizován.

Když se spouštěč spustí, spustí následující kód pouze v případě, že je tato podmínka pravdivá.

Spustit spouštěč

Vložíme řádek, ale do c1 vložíme pouze hodnotu sloupec.

INSERT INTO t1 (c1) 
VALUES (1);

SELECT * FROM t1;

Výsledek:

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

Podle očekávání se spustilo pravidlo a sloupec c3 byl také aktualizován.

Stalo se to, protože jsem zahrnul INSERT argument v definici mého spouštěče (tj. zadal jsem AFTER INSERT, UPDATE což znamená, že spouštěč se spustí při každém vložení nebo aktualizaci dat). Kdybych uvedl pouze AFTER UPDATE , nespustil by se, když jsem vložil data – spustil by se pouze tehdy, když aktualizuji existující data.

Pamatujte, že tabulka byla definována pomocí DEFAULT 0 , takže sloupec c2 má výchozí hodnotu nula.

Nyní aktualizujme c1 sloupec.

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

SELECT * FROM t1;

Výsledek:

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

Opět c3 sloupec byl aktualizován spolu s c1 .

Nyní provedeme aktualizaci c2 sloupec (tento sloupec není součástí pravidla).

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

SELECT * FROM t1;

Výsledek:

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

Takže tentokrát c2 byl aktualizován, ale c3 nebyl. Je to proto, že c1 sloupec nebyl aktualizován a náš spouštěč aktualizuje pouze c3 když c1 je aktualizován.

Totéž by se stalo, kdybychom vložili řádek bez určení c1 v INSERT prohlášení.

Co když aktualizuji sloupec se stejnou hodnotou?

Pokud aktualizujete sloupec se stejnou hodnotou, UPDATE() funkce vrátí true.

Zde je příklad.

Z našich předchozích příkladů víme, že sloupec c1 obsahuje hodnotu 2 .

Pojďme explicitně aktualizovat tento sloupec se stejnou hodnotou:1

UPDATE t1 
SET c1 = 2
WHERE id = 1;

SELECT * FROM t1;

Výsledek:

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

Takže teď c3 se zvýšil, i když hodnota pro c1 je stále stejný.

Udělejme to znovu, ale tentokrát to nastavte na sebe (tj. změňte c1 = 1 na c1 = c1 ).

UPDATE t1 
SET c1 = c1
WHERE id = 1;

SELECT * FROM t1;

Výsledek:

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

Opět c3 se zvýšil.

Neúspěšné pokusy o aktualizaci

Je důležité si uvědomit, že UPDATE() funkce pouze indikuje, zda INSERT nebo UPDATE pokus byl vytvořen v určeném sloupci tabulky nebo pohledu. Pokud byl pokus neúspěšný, bude stále vracet hodnotu true.


  1. Automatický sběr dat změn databázového schématu na MS SQL Server

  2. Chyba při připojování k postgresql pomocí sqlalchemy

  3. ERROR 1396 (HY000):Operace CREATE USER selhala pro 'jack'@'localhost'

  4. Je předpona sp_ stále ne-ne?