inserted
е псевдотаблица и определено съдържа всички правилни редове, които са били засегнати от UPDATE
израз (и предполагам, че DISTINCT
не е необходимо, ако ID
първичен ключ - въпреки че е трудно да се каже каква е таблицата с име като 121s
). Дали всички те наистина са променени стойности е друго нещо, което може да помислите за валидиране, преди да приложите модифицираната дата/час. Като изключим това, вероятно бих го направил по следния начин:
ALTER TRIGGER [dbo].[trg_121s]
ON [dbo].[121s]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE t SET modified = CURRENT_TIMESTAMP
FROM dbo.[121s] AS t
WHERE EXISTS (SELECT 1 FROM inserted WHERE ID = t.ID);
-- WHERE EXISTS is same as INNER JOIN inserted AS i ON t.ID = i.ID;
END
GO
Ако искате да имате 100% сигурна гаранция, че всички те са актуализирани с едно и също времево клеймо (въпреки че не знам дали някога съм виждал множество стойности в този случай на употреба):
ALTER TRIGGER [dbo].[trg_121s]
ON [dbo].[121s]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ts DATETIME;
SET @ts = CURRENT_TIMESTAMP;
UPDATE t SET modified = @ts
FROM dbo.[121s] AS t
INNER JOIN inserted AS i
ON t.ID = i.ID;
END
GO
И ако искате да сте сигурни, че актуализацията се извършва само ако, да речем, колоната foo
променена стойност, можете да кажете:
UPDATE t SET modified = @ts
FROM dbo.[121s] AS t
INNER JOIN inserted AS i
ON t.ID = i.ID
AND t.foo <> i.foo;
Това е общият модел, но става по-сложен, ако foo
е nullable, тъй като SQL Server няма да може да намери съответствие на редове, където едната страна има стойност, а другата не (или и двете не). В такъв случай бихте направили следното:
AND
(
t.foo <> i.foo
OR (t.foo IS NULL AND i.foo IS NOT NULL)
OR (t.foo IS NOT NULL AND i.foo IS NULL)
);
Някои хора ще кажат „Мога просто да използвам COALESCE или ISNULL срещу някаква магическа стойност“ като това:
WHERE COALESCE(t.foo, 'magic') <> COALESCE(i.foo, 'magic')
...и ще ви предупредя за това, защото постоянно ще търсите някаква магическа стойност, която не може да съществува в данните.