web-dev-qa-db-ja.com

SQL Server After Insertトリガーがアクションを実行しない

2つの挿入後トリガーと1つの代わりの挿入トリガーに問題があります。 After Insertトリガーはいくつかのアクションを実行する必要がありますが、そのアクションは発生しません。

代わりにトリガーが発火すると、後トリガーのアクションが正常に機能します。

説明させてください:

代わりのトリガーは、ID値がNullかどうかを検証します。そうである場合、トリガーはテーブル(TRADE_APPR)SQL ServerシーケンスからのID値を入力します。

代わりにトリガーがアクションを実行すると、挿入後トリガーもアクションを実行します。

私の代わりの挿入トリガーのコードはこれです:

ALTER TRIGGER [ConfirmMgr].[TG_TRADE_APPR_BER_I] 
ON [ConfirmMgr].TRADE_APPR] 
INSTEAD OF INSERT
AS
   DECLARE
      @user_name            varchar(50),
      @appr_username        varchar(50),
      @appr_id          int,
      @v_id             int,
      @appr_timestamp       datetime
BEGIN 
    SELECT @appr_username = APPR_BY_USERNAME FROM inserted

    IF (@appr_username) IS NULL
    BEGIN
            SELECT @user_name = SUSER_NAME()
            UPDATE tbl SET APPR_BY_USERNAME = UPPER(@user_name)
            FROM ConfirmMgr.TRADE_APPR tbl
            INNER JOIN inserted i ON tbl.ID = i.ID
    END

    SELECT @appr_id = i.ID FROM inserted i

    IF (@appr_id) IS NULL
    BEGIN
        INSERT ConfirmMgr.TRADE_APPR
            SELECT 
                NEXT VALUE FOR ConfirmMgr.SEQ_TRADE_APPR,
                i.TRADE_ID,
                i.APPR_FLAG,
                ISNULL(i.APPR_TIMESTAMP_GMT,GETDATE()),
                ISNULL(i.APPR_BY_USERNAME, UPPER(SUSER_NAME()))
            FROM inserted i         
        END
    RETURN          
END

あなたが私のコードでチェックできるように、検証されたトリガーの代わりにこれはuser_nameまたはIDがNullの場合にアクションを実行します。

Null値を送信すると、トリガーは正常に機能し、Afterトリガーも機能します。

重要なのは、IDを含む正しい値を送信すると、レコードが挿入されず、挿入後トリガーがアクションを実行しないため、挿入アクションはレコードを保存しません。

正しい値を送信することを理解しています。このようなトリガーではなく、何かを実行またはブロックするべきではありません。

代わりに挿入トリガーを無効にするテストを実行しました。レコードは保存され、挿入後トリガーは正常に機能します。

私の質問は次のとおりです。権利の値を送信すると、代わりにInsert Of Insertトリガーが挿入アクションに影響を与えるのはなぜですか。

以下は、挿入後トリガーの1つにあるコードです。

アドバイスありがとうございます

ALTER TRIGGER ConfirmMgr.TG_TRADE_APPR_AER_I
ON ConfirmMgr.TRADE_APPR
AFTER INSERT
AS
/******************************************************************************
*
* AUTHOR:       JAVIER MONTERO - 08/19/2015
* DB:           SQL SERVER 2012 OR HIGHER
* VERSION:      1.0
* DESCRIPTION:  TRIGGER FOR UPDATE THE FIELD FINAL_APPROVAL_FLAG, 
                FINAL_APPROVAL_TIMESTAMP_GMT AND TRANSACTION_SEQ
                IN TABLE TRADE_SUMMARY WHEN A INSERT ACTION IS FIRED IN
                TRADE_APPR TABLE 
* DEPENDECIES:  TABLE TRADE_SUMMARY AND SEQUENCE SEQ_TRADE_SUMMARY_TRANSACTION
*
*******************************************************************************/
DECLARE 
@v_id       int

BEGIN
        /*The process collect the trade_id that is coming in the inserted values*/
        SELECT @v_id = ts.TRADE_ID
        FROM ConfirmMgr.TRADE_SUMMARY ts
        JOIN inserted i
        ON ts.TRADE_ID = i.TRADE_ID
        print cast(@v_id as varchar)
        /*The trade_id saved in the local variable @v_id is validated is different to Null*/
        IF (@v_id) IS NOT NULL 
        BEGIN
            /*Finally we update the fields FINAL_APPROVAL_FLAG, FINAL_APPROVAL_TIMESTAMP_GMT and TRANSACTION_SEQ 
            in the table TRADE_SUMMARY also it use a SQL Sequence to set the TRANSACTION SEQUENCE value in the table */
            UPDATE ts
            SET ts.FINAL_APPROVAL_FLAG = i.APPR_FLAG,
            ts.FINAL_APPROVAL_TIMESTAMP_GMT = i.APPR_TIMESTAMP_GMT,
            ts.TRANSACTION_SEQ = NEXT VALUE FOR ConfirmMgr.SEQ_TRADE_SUMMARY_TRANSACTION
            FROM ConfirmMgr.TRADE_SUMMARY ts
            INNER JOIN inserted i
            ON ts.TRADE_ID = i.TRADE_ID
        END
END
2
jmonterohn

INSTEAD OF INSERTトリガーはアクションを実行します代わりに元のINSERTが行っていたであろうこと。

コードで、@appr_usernameまたは@appr_idのいずれかがNULLの場合、ベーステーブルに何らかの変更(挿入または更新)が行われます。

それ以外の場合、トリガーによって何も実行されない(影響を受ける行がない)ため、AFTERトリガーはスキップされます。結局のところ、SQL Serverは、INSTEAD OFトリガーが何もしなかった場合、AFTERトリガーが行うことは何もできないと考えています。

サーバー構成オプション nested triggers (SSMS Advanced Serverの[プロパティ]タブでAllow Triggers to Fire Othersとして表示)が1(デフォルト)に設定されている場合も、非常に混乱する動作が発生する可能性があることに注意してください。 。

そのリンクから:

ネストされたトリガーオプションは、AFTERトリガーをカスケードできるかどうかを制御します。つまり、別のトリガーを開始するアクション、別のトリガーを開始するアクションなどを実行します。ネストされたトリガーが0に設定されている場合、AFTERトリガーはカスケードできません。ネストされたトリガーが1(デフォルト)に設定されている場合、AFTERトリガーは32レベルまでカスケードできます。 INSTEAD OFトリガーは、このオプションの設定に関係なくネストできます。

6
Paul White 9