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
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トリガーは、このオプションの設定に関係なくネストできます。