inserted
er en pseudo-tabel, og den indeholder helt sikkert alle de rigtige rækker, der blev påvirket af UPDATE
sætning (og jeg antager DISTINCT
er ikke nødvendigt, hvis ID
en primær nøgle - selvom det er svært at sige, hvad tabellen er med et navn som 121s
). Om dem alle faktisk havde ændret sig værdier er en anden ting, du kan overveje at validere, før du anvender den ændrede dato/tid. Bortset fra det, ville jeg nok gøre det på denne måde:
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
Hvis du vil have en 100 % idiotsikker garanti for, at de alle er opdateret med det samme tidsstempel (selvom jeg ikke ved, om jeg nogensinde har set flere værdier i dette tilfælde):
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
Og hvis du vil sikre dig, at opdateringen kun sker, hvis f.eks. kolonnen foo
ændret værdi, kan man sige:
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;
Det er det generelle mønster, men det bliver mere komplekst, hvis foo
er nullbar, da SQL Server ikke vil være i stand til at matche på rækker, hvor den ene side har en værdi, og den anden ikke har (eller begge ikke har). I så fald ville du gøre dette:
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)
);
Nogle mennesker vil sige "Jeg kan bare bruge COALESCE eller ISNULL mod en eller anden magisk værdi" sådan her:
WHERE COALESCE(t.foo, 'magic') <> COALESCE(i.foo, 'magic')
...og jeg vil advare dig mod dette, for du vil konstant søge efter en eller anden magisk værdi, der ikke kan eksistere i dataene.