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

Vytvořte spouštěč „místo“ na serveru SQL Server

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 .


  1. Jak získat včerejší datum v Oracle

  2. Počítejte záznamy pro každý měsíc v roce

  3. Získejte datum/čas z unixového časového razítka v SQLite

  4. Proč každá malá firma potřebuje databázi