Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Създайте тригер „Вместо“ в SQL Server

Когато създадете задействане в 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 .


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да намерите най-бавните заявки

  2. Конкатениране на стойностите на редове T-SQL

  3. Принудително изчакване на заявка в SQL Server

  4. Върнете оригиналното начало на колона за идентичност в SQL Server

  5. Има ли комбинация от LIKE и IN в SQL?