Когато създадете задействане в SQL Server, имате възможност да го задействате във връзка с оператора за задействане (т.е. SQL израза, който е задействал тригера) или да го задействате вместо на това изявление.
За да задейства спусъка вместо на задействащия израз, използвайте INSTEAD OF
аргумент.
Това е в контраст с използването на FOR
или AFTER
аргументи. Когато използвате тези аргументи, тригерът се задейства само когато всички операции, посочени в задействащия SQL израз, са стартирани успешно.
Пример
Създайте примерна таблица:
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
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);
Вмъкнете примерен ред:
INSERT INTO t1 (c1, c2, c3)
VALUES (1, 1, 1);
SELECT * FROM t1;
Ето какво имаме досега:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 1 | +------+------+------+------+
Сега нека изпълним UPDATE
изявление срещу таблицата (това ще задейства спусъка).
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Резултат:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 2 | +------+------+------+------+
Както се очакваше, UPDATE
изявлението в задействащия оператор беше заменено с това в тригера.
Моят тригер посочи, че всеки път, когато има опит за актуализиране на таблицата, актуализирайте c3
вместо колона.
Изпълнявайте само когато се актуализира конкретна колона
Можете също да използвате UPDATE()
функция за определяне на код, който да се изпълнява само когато се актуализира определена колона.
Например, можем да променим нашия тригер, както следва:
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;
Сега стартирайте предишната UPDATE
отново изявление:
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Резултат:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Отново c3
колоната се увеличава.
Но сега нека се опитаме да актуализираме c2
колона:
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Резултат:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Нищо не се променя. c3
колоната остава същата.
Дори не c2
колоната се актуализира. Това е така, защото тригерът все още работи вместо задействащия израз.
Изпълнете Trigger вместо DELETE
Можем да модифицираме тригера да се изпълнява вместо всяко DELETE
изявления.
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);
Сега нека се опитаме да изтрием всички редове и след това да изберете всички редове от таблицата.
DELETE FROM t1;
SELECT * FROM t1;
Резултат:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 4 | +------+------+------+------+
Имайте предвид, че за да работи този тригер правилно, трябваше да потърся deleted
таблица в моя тригер (за разлика от inserted
таблица в предишните примери).
Тези две таблици са създадени и управлявани от SQL Server.
deleted
таблицата съхранява копия на засегнатите редове по време на DELETE
и UPDATE
изявления. По време на изпълнението на DELETE
или UPDATE
оператор, редовете се изтриват от таблицата за задействане и се прехвърлят в изтритата таблица.
inserted
таблицата съхранява копия на засегнатите редове по време на INSERT
и UPDATE
изявления. По време на транзакция за вмъкване или актуализиране, нови редове се добавят както към вмъкнатата таблица, така и към таблицата за задействане. Редовете във вмъкнатата таблица са копия на новите редове в таблицата за задействане.
Някои ограничения, които трябва да имате предвид
Можете да дефинирате максимум един INSTEAD OF
тригер за INSERT
, UPDATE
или DELETE
изявление върху таблица или изглед.
Не можете да дефинирате INSTEAD OF
задейства в обновяеми изгледи, които използват WITH CHECK OPTION
.