V SQL Server můžete použít CREATE TRIGGER
příkaz k vytvoření spouštěče.
Spouštěč je speciální typ uložené procedury, která se automaticky spustí, když na databázovém serveru dojde k události.
Můžete vytvořit spouštěč DML, spouštěč DDL nebo spouštěč přihlášení.
Tento článek poskytuje příklad vytvoření spouštěče DML.
Co je spouštěč DML?
Spouštěč DML je spouštěč, který se spustí, když se uživatel pokusí upravit data prostřednictvím události jazyka manipulace s daty (DML).
Mezi události DML patří INSERT
, UPDATE
nebo DELETE
prohlášení. Spouštěče DML lze použít k vynucení obchodních pravidel a integrity dat, dotazování na jiné tabulky a zahrnutí složitých příkazů T-SQL.
Spouštěč a příkaz, který jej spouští, jsou považovány za jednu transakci, kterou lze vrátit zpět ze spouštěče.
Příklad
Zde je příklad demonstrující, jak fungují spouštěče DML.
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);
V tomto příkladu vytvořím tabulku a také vytvořím spouštěč, který se spustí vždy, když je do tabulky vložen nebo aktualizován řádek.
V tomto případě spouštěč přidá 1 k c3
při každém vložení nebo aktualizaci dat.
Nazval jsem spouštěč trg_t1
. Sledoval jsem tuto část pomocí ON t1
, což znamená, že spouštěč bude spuštěn v tabulce nazvané t1
.
Alternativně můžete určit zobrazení, na kterém se má spouštěč spouštět, i když na zobrazení můžete odkazovat pouze pomocí INSTEAD OF
spouštěč (v tomto případě nahraďte AFTER
s INSTEAD OF
). Také nemůžete definovat spouštěče DML pro místní nebo globální dočasné tabulky.
AFTER
určuje, že aktivační událost DML se spustí pouze tehdy, když byly úspěšně spuštěny všechny operace uvedené ve spouštěcím příkazu SQL. Alternativně můžete zadat FOR
tady.
Další alternativou je použití INSTEAD OF
, který spustí spouštěč místo spouštěcího příkazu SQL. To proto přepíše akce spouštěcích příkazů.
Co je inserted
Tabulka?
V mém spouštěči jsem schopen zjistit, který řádek byl aktualizován dotazem na inserted
tabulka.
SQL Server vytváří a spravuje tabulku s názvem inserted
, což je dočasná tabulka rezidentní v paměti, která ukládá kopie dotčených řádků během INSERT
a UPDATE
prohlášení. Během transakce vložení nebo aktualizace se do inserted
přidají nové řádky stůl a spouštěcí stůl. Řádky ve vložené tabulce jsou kopiemi nových řádků v tabulce spouštěčů.
SQL Server také vytváří a udržuje podobnou tabulku s názvem delete, která 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.
Spusťte spouštěč
Nyní, když byla tabulka a její spouštěč vytvořeny, spusťte několik příkazů SQL, které ji spustí.
INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Výsledek:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 0 | 1 | +------+------+------+------+
Můžeme tedy vidět, že spoušť fungovala podle očekávání. Když jsem vložil řádek, zadal jsem pouze hodnotu pro c1
ale spouštěč zajistil, že c3
sloupec byl také aktualizován.
Všimněte si, že výchozí hodnota pro všechny sloupce je 0
(jak bylo uvedeno při vytváření tabulky) a spouštěč k tomu přidal 1.
Provedeme UPDATE
operace na stejném sloupci.
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Výsledek:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 0 | 2 | +------+------+------+------+
Ještě jednou, c3
sloupec byl také aktualizován spouštěčem.
Nyní aktualizujme c2
sloupec.
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Výsledek:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 3 | +------+------+------+------+
Takže ještě jednou, c3
sloupec je aktualizován spouštěčem.
Toto konkrétní pravidlo se spustí vždy, když je aktualizován jakýkoli jiný sloupec ve stejném řádku.
Můžete také použít IF UPDATE(column_name)
pro kontrolu aktualizace jednoho sloupce nebo COLUMNS_UPDATED()
pro kontrolu aktualizací ve více sloupcích.