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

SQLServerで「代わりの」トリガーを作成する

    SQL Serverでトリガーを作成する場合、トリガーステートメント(つまり、トリガーを起動したSQLステートメント)と組み合わせて起動するか、代わりに起動するかを選択できます。 その声明の。

    代わりにトリガーを起動するには トリガーステートメントのINSTEADOFを使用します 引数。

    これは、 FORを使用するのとは対照的です。 またはAFTER 引数。これらの引数を使用すると、トリガーとなるSQLステートメントで指定されたすべての操作が正常に起動した場合にのみトリガーが起動します。

    サンプルテーブルを作成します:

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

    トリガーを作成します:

    CREATE TRIGGER trg_t1
    ON t1
    INSTEAD OF UPDATE
    AS
    UPDATE t1
    SET c3 = c3 + 1
    WHERE id IN (SELECT DISTINCT id FROM inserted);

    サンプル行を挿入します:

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

    これまでのところ、次のとおりです。

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

    それでは、 UPDATEを実行してみましょう。 テーブルに対するステートメント(これによりトリガーが起動されます)。

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

    結果:

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

    予想どおり、 UPDATE トリガーステートメントのステートメントは、トリガーのステートメントに置き換えられました。

    私のトリガーは、テーブルの更新が試行されるたびに、 c3を更新するように指定しました 代わりに列。

    特定の列が更新された場合にのみ実行

    UPDATE()を使用することもできます 指定した列が更新されたときにのみ実行するコードを指定する関数。

    たとえば、トリガーを次のように変更できます。

    ALTER TRIGGER trg_t1
    ON t1
    INSTEAD OF UPDATE
    AS
    IF ( UPDATE(c1) )
    BEGIN
    UPDATE t1
    SET c3 = c3 + 1
    WHERE id IN (SELECT DISTINCT id FROM inserted)
    END;

    次に、前の UPDATEを実行します もう一度声明:

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

    結果:

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

    繰り返しますが、 c3 列がインクリメントされます。

    しかし、今度は c2を更新してみましょう。 列:

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

    結果:

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

    何も変わりません。 c3 列は同じままです。

    c2でさえありません 列が更新されます。これは、トリガーステートメントの代わりにトリガーが引き続き実行されるためです。

    DELETEの代わりにトリガーを実行する

    DELETEの代わりに実行するようにトリガーを変更できます ステートメント。

    ALTER TRIGGER trg_t1
    ON t1
    INSTEAD OF DELETE
    AS
    UPDATE t1
    SET c3 = c3 + 1
    WHERE id IN (SELECT DISTINCT id FROM deleted);

    それでは、すべての行を削除してから、テーブルからすべての行を選択してみましょう。

    DELETE FROM t1;
    
    SELECT * FROM t1;

    結果:

    +------+------+------+------+
    | id   | c1   | c2   | c3   |
    |------+------+------+------|
    | 1    | 1    | 1    | 4    |
    +------+------+------+------+

    このトリガーが正しく機能するためには、 deleteedにクエリを実行する必要があることに注意してください。 トリガーのテーブル(挿入とは対照的) 前の例の表)。

    これらの2つのテーブルは、SQLServerによって作成および管理されます。

    削除 テーブルには、 DELETE中に影響を受ける行のコピーが格納されます およびUPDATE ステートメント。 DELETEの実行中 またはUPDATE ステートメントでは、行はトリガーテーブルから削除され、削除されたテーブルに転送されます。

    挿入 テーブルには、 INSERT中に影響を受ける行のコピーが格納されます およびUPDATE ステートメント。挿入または更新トランザクション中に、挿入されたテーブルとトリガーテーブルの両方に新しい行が追加されます。挿入されたテーブルの行は、トリガーテーブルの新しい行のコピーです。

    注意すべきいくつかの制限

    最大1つのINSTEADOFを定義できます INSERTごとのトリガー 、 UPDATE 、または DELETE テーブルまたはビューのステートメント。

    INSTEAD OFを定義することはできません WITH CHECK OPTIONを使用する更新可能なビューでトリガーします 。


    1. Pythonを介してPostgreSQLに列コメントを挿入するにはどうすればよいですか?

    2. MariaDBでサブストリングを置き換える2つの方法

    3. WHERE句でmysqlconcat()を使用していますか?

    4. OracleApplicationExpressでのSQL入門