Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Déclencher et mettre à jour une ligne dans SQL Server après sa mise à jour

inserted est une pseudo-table et elle contient définitivement toutes les bonnes lignes qui ont été affectées par la UPDATE déclaration (et je suppose que DISTINCT n'est pas nécessaire, si ID une clé primaire - bien qu'il soit difficile de dire ce qu'est la table avec un nom comme 121s ). Si tous avaient réellement changé values ​​est une autre chose que vous pouvez envisager de valider avant d'appliquer la date/heure modifiée. Sinon, je procéderais probablement de cette façon :

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

Si vous voulez avoir une garantie infaillible à 100 % qu'ils sont tous mis à jour avec le même horodatage (bien que je ne sache pas si j'ai déjà vu plusieurs valeurs dans ce cas d'utilisation) :

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

Et si vous voulez vous assurer que la mise à jour ne se produit que si, par exemple, la colonne foo valeur modifiée, vous pourriez 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;

C'est le modèle général, mais il devient plus complexe si foo est nullable, car SQL Server ne pourra pas faire correspondre les lignes où un côté a une valeur et l'autre non (ou les deux non). Dans ce cas, vous feriez ceci :

   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)
   );

Certaines personnes diront "Je peux simplement utiliser COALESCE ou ISNULL contre une valeur magique" comme ceci :

WHERE COALESCE(t.foo, 'magic') <> COALESCE(i.foo, 'magic')

...et je vous mets en garde contre cela, car vous serez constamment à la recherche d'une valeur magique qui ne peut pas exister dans les données.