SQL Server има UPDATE()
функция, която можете да използвате във вашите DML тригери, за да проверите дали конкретна колона е актуализирана или не.
Въпреки че тази функция приема само една колона, нищо не ви пречи да включите няколко UPDATE()
клаузи с AND
или OR
за да тествате за множество актуализации на колони.
Пример
Ето таблицата:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0,
c4 int DEFAULT 0
);
И ето спусъка:
CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE(c1) OR UPDATE(c2) )
BEGIN
UPDATE t1
SET c4 = c4 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
В този случай c4
колоната ще се увеличава само ако c1
или c2
колоните бяха актуализирани. Това ще се случи дори ако само една от тези две колони се актуализира (поради това, че използвам OR
за разлика от AND
).
Сега нека тестваме тригера, като вмъкнем данни в c1
.
INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Резултат:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 0 | 0 | 1 | +------+------+------+------+------+
Както се очаква, c4
също беше актуализиран, когато c1
бе актуализиран.
Това важи и винаги, когато c2
се актуализира.
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Резултат:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 0 | 2 | +------+------+------+------+------+
И, разбира се, ще се приложи, когато и двете се актуализират.
Въпреки това няма прилага се, ако актуализираме c3
(но не и c1
или c2
).
UPDATE t1
SET c3 = c3 + 1
WHERE id = 1;
SELECT * FROM t1;
Резултат:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 1 | 2 | +------+------+------+------+------+
Изискване и двете колони да бъдат актуализирани
Можем да променим OR
към AND
за да посочите, че c4
колоната се актуализира само ако и двете c1
и c2
се актуализират.
Нека променим нашия тригер, за да посочим това:
ALTER TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE(c1) AND UPDATE(c2) )
BEGIN
UPDATE t1
SET c4 = c4 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
Сега актуализирайте c1
само.
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Резултат:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 2 | 1 | 1 | 2 | +------+------+------+------+------+
Така че c1
беше актуализиран, както е посочено, но c4
не беше.
Същото ще се случи, ако актуализираме c2
но не и c1
.
Но сега нека актуализираме и двата c1
и c2
.
UPDATE t1
SET c1 = c1 + 1, c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Резултат:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 3 | 2 | 1 | 3 | +------+------+------+------+------+
Както се очакваше, този път c4
също беше актуализиран.
Неуспешни актуализации
Важно е да се отбележи, че UPDATE()
функцията просто показва дали INSERT
или UPDATE
опит е направено върху определена колона на таблица или изглед. Той пак ще върне true, ако опитът е бил неуспешен.
Функцията COLUMNS_UPDATED
Друг начин да проверите за актуализации в множество колони е да използвате COLUMNS_UPDATED
функция.
Тази функция връща varbinary битов модел, указващ вмъкнатите или актуализирани колони на таблица или изглед.
За повече информация вижте документацията на Microsoft за COLUMNS_UPDATED
.