sql >> データベース >  >> RDS >> Sqlserver

更新された後、SQLServerの行をトリガーして更新します

    inserted は疑似テーブルであり、UPDATEの影響を受けたすべての正しい行が確実に含まれています ステートメント(そして私はDISTINCTを想定しています IDの場合、必要ありません 主キー-121sのような名前でテーブルが何であるかを判断するのは難しいですが )。それらすべてが実際に変更されたかどうか 値は、変更された日付/時刻を適用する前に検証することを検討できるもう1つのことです。それを除けば、私はおそらくこのようにするでしょう:

    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
    

    すべてが同じタイムスタンプで更新されることを100%確実に保証したい場合(このユースケースで複数の値を見たことがあるかどうかはわかりませんが):

    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
    

    また、たとえば、列fooの場合にのみ更新が行われるようにする場合は、 値が変更された場合、次のように言うことができます:

      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;
    

    これは一般的なパターンですが、fooの場合はさらに複雑になります SQL Serverは、一方の側に値があり、もう一方の側に値がない(または両方に値がない)行では一致できないため、null許容です。その場合、これを行います:

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

    一部の人々は、次のように「魔法の値に対してCOALESCEまたはISNULLを使用できます」と言うでしょう:

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

    ...そして、データに存在できない魔法の値を常に探しているので、これに対して警告します。



    1. PDO::fetchAllとPDO::fetchのループ

    2. PL / SQLにファイルが存在するかどうかを確認する方法は?

    3. SQLAlchemyセッションオブジェクトにセッションを設定します

    4. SQLで複数の値の変数を宣言します