Když vytvoříte spouštěč na serveru SQL Server, máte možnost jej spustit ve spojení se spouštěcím příkazem (tj. příkazem SQL, který spouštěč spustil), nebo jej spustit místo tohoto prohlášení.
Chcete-li spouštět místo toho spouštěcího příkazu použijte INSTEAD OF
argument.
To je v kontrastu s použitím FOR
nebo AFTER
argumenty. Když použijete tyto argumenty, spouštěč se spustí pouze tehdy, když byly úspěšně spuštěny všechny operace uvedené ve spouštěcím příkazu SQL.
Příklad
Vytvořte vzorovou tabulku:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
Vytvořte spouštěč:
CREATE TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);
Vložte ukázkový řádek:
INSERT INTO t1 (c1, c2, c3)
VALUES (1, 1, 1);
SELECT * FROM t1;
Zde je to, co zatím máme:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 1 | +------+------+------+------+
Nyní spusťte UPDATE
příkaz proti tabulce (to spustí spouštěč).
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Výsledek:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 2 | +------+------+------+------+
Jak bylo očekáváno, UPDATE
příkaz ve spouštěcím příkazu byl nahrazen příkazem ve spouštěči.
Můj spouštěč určil, že kdykoli dojde k pokusu o aktualizaci tabulky, aktualizujte c3
místo toho.
Spustit pouze při aktualizaci konkrétního sloupce
Můžete také použít UPDATE()
funkce k určení kódu, který se má spustit pouze při aktualizaci zadaného sloupce.
Náš spouštěč bychom mohli změnit například takto:
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;
Nyní spusťte předchozí UPDATE
znovu prohlášení:
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Výsledek:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Opět c3
sloupec se zvýší.
Nyní se však pokusíme aktualizovat c2
sloupec:
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Výsledek:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Nic se nemění. c3
sloupec zůstává stejný.
Dokonce ani c2
sloupec je aktualizován. Důvodem je, že spouštěč stále běží namísto spouštěcího příkazu.
Spustit Trigger namísto DELETE
Spouštěč můžeme upravit tak, aby se spouštěl namísto DELETE
prohlášení.
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);
Nyní se pokusíme odstranit všechny řádky a poté vybrat všechny řádky z tabulky.
DELETE FROM t1;
SELECT * FROM t1;
Výsledek:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 4 | +------+------+------+------+
Všimněte si, že aby tento spouštěč správně fungoval, musel jsem zadat dotaz na deleted
tabulka v mém spouštěči (na rozdíl od inserted
tabulka v předchozích příkladech).
Tyto dvě tabulky vytváří a spravuje SQL Server.
deleted
tabulka ukládá kopie dotčených řádků během DELETE
a UPDATE
prohlášení. Během provádění příkazu DELETE
nebo UPDATE
příkazem, jsou řádky odstraněny z tabulky spouštěčů a přeneseny do odstraněné tabulky.
inserted
tabulka ukládá kopie dotčených řádků během INSERT
a UPDATE
prohlášení. Během vkládání nebo aktualizace transakce jsou přidány nové řádky jak do vložené tabulky, tak do tabulky aktivačních událostí. Řádky ve vložené tabulce jsou kopiemi nových řádků v tabulce spouštěčů.
Některá omezení, která je třeba mít na paměti
Můžete definovat maximálně jeden INSTEAD OF
spouštěč za INSERT
, UPDATE
nebo DELETE
výpis na stůl nebo pohled.
Nemůžete definovat INSTEAD OF
spouští u aktualizovatelných pohledů, které používají WITH CHECK OPTION
.