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

特定の列が更新された場合にのみトリガーを実行する(SQL Server)

    SQLServerにはUPDATE()があります 特定の列が更新されているかどうかを確認するためにDMLトリガー内で使用できる関数。

    この関数は1つの列のみを受け入れますが、複数のUPDATE()を含めることを妨げるものは何もありません。 ANDを含む句 またはOR 複数の列の更新をテストします。

    表は次のとおりです:

    CREATE TABLE t1 (
        id int IDENTITY(1,1) NOT NULL,
        c1 int DEFAULT 0,
        c2 int DEFAULT 0,
        c3 int DEFAULT 0,
        c4 int DEFAULT 0
    );

    そして、これがトリガーです:

    CREATE TRIGGER trg_t1
    ON t1
    AFTER INSERT, UPDATE
    AS
    IF ( UPDATE(c1) OR UPDATE(c2) )
    BEGIN
    UPDATE t1
    SET c4 = c4 + 1
    WHERE id IN (SELECT DISTINCT id FROM inserted)
    END;

    この場合、c4 列は、c1のいずれかである場合にのみインクリメントされます またはc2 列が更新されました。これは、これら2つの列の1つだけが更新された場合でも発生します(ORを使用しているため) ANDとは対照的に 。

    次に、c1にデータを挿入してトリガーをテストしましょう 。

    INSERT INTO t1 (c1) 
    VALUES (1);
    
    SELECT * FROM t1;

    結果:

    +------+------+------+------+------+
    | id   | c1   | c2   | c3   | c4   |
    |------+------+------+------+------|
    | 1    | 1    | 0    | 0    | 1    |
    +------+------+------+------+------+

    予想通り、c4 c1のときにも更新されました 更新されました。

    これは、c2の場合にも適用されます 更新されます。

    UPDATE t1 
    SET c2 = c2 + 1
    WHERE id = 1;
    
    SELECT * FROM t1;

    結果:

    +------+------+------+------+------+
    | id   | c1   | c2   | c3   | c4   |
    |------+------+------+------+------|
    | 1    | 1    | 1    | 0    | 2    |
    +------+------+------+------+------+

    そしてもちろん、両方が更新されたときにも適用されます。

    ただし、しません c3を更新する場合に適用します (ただし、c1ではありません またはc2 )。

    UPDATE t1 
    SET c3 = c3 + 1
    WHERE id = 1;
    
    SELECT * FROM t1;

    結果:

    +------+------+------+------+------+
    | id   | c1   | c2   | c3   | c4   |
    |------+------+------+------+------|
    | 1    | 1    | 1    | 1    | 2    |
    +------+------+------+------+------+

    両方の列を更新する必要があります

    ORを変更できます AND c4を指定します 列は、両方のc1の場合にのみ更新されます および c2 更新中です。

    これを指定するためにトリガーを変更しましょう:

    ALTER TRIGGER trg_t1
    ON t1
    AFTER INSERT, UPDATE
    AS
    IF ( UPDATE(c1) AND UPDATE(c2) )
    BEGIN
    UPDATE t1
    SET c4 = c4 + 1
    WHERE id IN (SELECT DISTINCT id FROM inserted)
    END;

    次に、c1を更新します のみ。

    UPDATE t1 
    SET c1 = c1 + 1
    WHERE id = 1;
    
    SELECT * FROM t1;

    結果:

    +------+------+------+------+------+
    | id   | c1   | c2   | c3   | c4   |
    |------+------+------+------+------|
    | 1    | 2    | 1    | 1    | 2    |
    +------+------+------+------+------+

    したがって、c1 指定どおりに更新されましたが、c4 そうではありませんでした。

    c2を更新した場合も同じことが起こります ただし、c1ではありません 。

    しかし、今度は両方のc1を更新しましょう および c2

    UPDATE t1 
    SET c1 = c1 + 1, c2 = c2 + 1
    WHERE id = 1;
    
    SELECT * FROM t1;

    結果:

    +------+------+------+------+------+
    | id   | c1   | c2   | c3   | c4   |
    |------+------+------+------+------|
    | 1    | 3    | 2    | 1    | 3    |
    +------+------+------+------+------+

    さすがに今回はc4 も更新されました。

    失敗した更新

    UPDATE()に注意することが重要です 関数は、INSERTかどうかを示すだけです。 またはUPDATE 試行 テーブルまたはビューの指定された列で作成されました。試行が失敗した場合でも、trueが返されます。

    COLUMNS_UPDATED関数

    複数の列にわたる更新を確認する別の方法は、COLUMNS_UPDATEDを使用することです。 機能。

    この関数はvarbinaryを返します テーブルまたはビューの挿入または更新された列を示すビットパターン。

    詳細については、COLUMNS_UPDATEDに関するMicrosoftのドキュメントを参照してください。 。


    1. SQLServerインデックスの破損を修復するための無料の方法

    2. テーブルから重複を削除します

    3. SQL Serverトランザクションログ—パート1

    4. 主キーを変更する