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