inserted
è una pseudo-tabella e contiene sicuramente tutte le righe corrette che sono state interessate da UPDATE
dichiarazione (e presumo DISTINCT
non è necessario, se ID
una chiave primaria, anche se è difficile dire quale sia la tabella con un nome come 121s
). Se tutti erano effettivamente cambiati valori è un'altra cosa che potresti considerare di convalidare prima di applicare la data/ora modificata. A parte questo, probabilmente lo farei in questo modo:
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
Se vuoi avere una garanzia infallibile al 100% che siano tutti aggiornati con lo stesso timestamp (anche se non so se ho mai visto più valori in questo caso d'uso):
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
E se vuoi assicurarti che l'aggiornamento avvenga solo se, diciamo, la colonna foo
cambiato valore, potresti dire:
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;
Questo è lo schema generale, ma diventa più complesso se foo
è nullable, poiché SQL Server non sarà in grado di trovare una corrispondenza su righe in cui un lato ha un valore e l'altro no (o entrambi non lo fanno). In tal caso faresti così:
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)
);
Alcune persone diranno "Posso semplicemente usare COALESCE o ISNULL contro un valore magico" in questo modo:
WHERE COALESCE(t.foo, 'magic') <> COALESCE(i.foo, 'magic')
...e ti metterò in guardia contro questo, perché sarai costantemente alla ricerca di un valore magico che non può esistere nei dati.