Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Wyzwalaj i aktualizuj do wiersza w SQL Server po jego aktualizacji

inserted jest pseudotablicą i na pewno zawiera wszystkie właściwe wiersze, na które wpłynęła UPDATE oświadczenie (i zakładam DISTINCT nie jest konieczne, jeśli ID klucz podstawowy - choć trudno powiedzieć, jaka jest tabela o nazwie takiej jak 121s ). Czy rzeczywiście wszystkie się zmieniły wartości to kolejna rzecz, którą możesz rozważyć przed zastosowaniem zmodyfikowanej daty/godziny. Poza tym prawdopodobnie zrobiłbym to w ten sposób:

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

Jeśli chcesz mieć 100% niezawodną gwarancję, że wszystkie są aktualizowane z tym samym znacznikiem czasu (chociaż nie wiem, czy kiedykolwiek widziałem wiele wartości w tym przypadku użycia):

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

A jeśli chcesz mieć pewność, że aktualizacja nastąpi tylko wtedy, gdy, powiedzmy, kolumna foo zmieniona wartość, możesz powiedzieć:

  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;

To jest ogólny wzorzec, ale staje się bardziej złożony, jeśli foo jest dopuszczalna, ponieważ SQL Server nie będzie w stanie dopasować się do wierszy, w których jedna strona ma wartość, a druga nie (lub obie nie). W takim przypadku zrobiłbyś to:

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

Niektórzy powiedzą „Mogę po prostu użyć COALESCE lub ISNULL przeciwko jakiejś magicznej wartości” w ten sposób:

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

...ostrzegam Cię przed tym, ponieważ będziesz ciągle szukał jakiejś magicznej wartości, która nie może istnieć w danych.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak utworzyć funkcję SQL Server, aby połączyć wiele wierszy z podzapytania w jedno pole rozdzielane?

  2. W Sql Server, jak obracać dla wielu kolumn

  3. Czy istnieje program SQL Server Profiler dla programu SQL Server Express?

  4. Jak zatrzymać kontekst zmienionej bazy danych, aby ... wiadomość?

  5. Dziennik transakcji SQL Server — część 2