Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Attiva e aggiorna su una riga in SQL Server dopo che è stata aggiornata

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.