sql >> Databasteknik >  >> RDS >> Sqlserver

Utlösa och uppdatera till en rad i SQL Server efter att den har uppdaterats

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.



  1. Gruppera rader med tanke på skillnaden mellan raderna

  2. % logga in i Javas PreparedStatement

  3. lagrade procedurer och mysql_insert_id-problem

  4. ny radavgränsare fungerar inte för group_concat-funktionen