inserted
är en pseudotabell och den innehåller definitivt alla rätt rader som påverkades av UPDATE
uttalande (och jag antar DISTINCT
är inte nödvändigt om ID
en primärnyckel - även om det är svårt att avgöra vad tabellen är med ett namn som 121s
). Om alla verkligen hade förändrats värden är en annan sak som du kan överväga att validera innan du tillämpar det ändrade datumet/tiden. Bortsett från det skulle jag förmodligen göra så här:
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
Om du vill ha en 100 % idiotsäker garanti för att de alla är uppdaterade med samma tidsstämpel (även om jag inte vet om jag någonsin har sett flera värden i det här användningsfallet):
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
Och om du vill säkerställa att uppdateringen bara sker om t.ex. kolumnen foo
ändrat värde kan man säga:
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 är det allmänna mönstret, men det blir mer komplext om foo
är nullbar, eftersom SQL Server inte kommer att kunna matcha på rader där den ena sidan har ett värde och den andra inte har det (eller båda inte har det). I så fall skulle du göra så här:
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)
);
Vissa människor kommer att säga "Jag kan bara använda COALESCE eller ISNULL mot något magiskt värde" så här:
WHERE COALESCE(t.foo, 'magic') <> COALESCE(i.foo, 'magic')
...och jag kommer att varna dig för detta, eftersom du ständigt kommer att leta efter något magiskt värde som inte kan finnas i datan.