Sybaseトリガーはどのような条件下で呼ばれませんか?
-
28-10-2019 - |
質問
Sybase ASEデータベースには、DocsとTransの2つのテーブルの更新時に起動されるトリガーがいくつかあります。
トリガーは、ここに示すように定義されています。
ドキュメントの場合:
CREATE TRIGGER dbo.Index_Change_Docs
ON dbo.docs
FOR INSERT,UPDATE AS
IF UPDATE(DOCTYPE) OR UPDATE(BATCH_NO) OR UPDATE(SCANDATE) OR
UPDATE(PERIOD_START_DATE) OR UPDATE(PERIOD_END_DATE)
OR UPDATE(DISPATCH_ID) OR UPDATE(DISPATCH_NAME) OR UPDATE(CHECKNUM) OR
UPDATE(CHECKAMT)
BEGIN
INSERT INTO
DOCID_SYNC (IS_DOC_ID, CRTN_DT, SYNC_STATUS_CDE)
SELECT Inserted.DOCID, GETDATE(), "N" FROM Inserted
END
トランスの場合:
CREATE TRIGGER dbo.Index_Change_Trans
ON dbo.Trans
FOR INSERT,UPDATE AS
IF UPDATE(TRANSNUM) OR UPDATE(CONTRACT) OR UPDATE(FRANCHISE) OR UPDATE(SSN) OR
UPDATE(STATE_CODE) OR UPDATE(TRANSTYPE)
OR UPDATE(AGENCYNUM) OR UPDATE(LOCKBOXBATCHNUM) OR UPDATE(PRODUCTCODE)
BEGIN
INSERT INTO
DOCID_SYNC (IS_DOC_ID, CRTN_DT, SYNC_STATUS_CDE)
SELECT DOCID, GETDATE(), "N" FROM DOCS
WHERE Transnum = (SELECT Inserted.TransNum from Inserted)
END
これらのトリガーの動作は、それらのテーブルの更新がどのように作成されるかによって異なります。
1つのケースでは、これらのテーブルは2つのストアドプロシージャ(INSERT_DOCS_SPおよびINSERT_TRANS_SP)を介して更新されます。これが発生すると、各トリガーが一度発射され(ドキュメント用に1回、トランス用)、すべてが予想どおりに機能します。
別のケースでは、これらのテーブルは、2つのデータベース更新を備えたSybaseトランザクション内で更新されます。ここで、最初の更新は、呼び出しアプリケーションのインラインSQLを介して行われます(トランストリガーを起動します。)2番目のアップデートは、ストアドプロシージャ-Anters_DOCS_SPを介して実行されます。
おそらく、私が理解していないトランザクションがどのように処理されるかについて何かがありますか?
解決 2
答えを見つけました - それは実行の順にあります。トリガーの1つは解雇されていないと思いました - この場合、index_change_transトリガー - 実際にはそうでした。ただし、このトリガーはドキュメントテーブルのエントリに依存しているため、結果は表示されませんでした。
INSERT INTO
DOCID_SYNC (IS_DOC_ID, CRTN_DT, SYNC_STATUS_CDE)
SELECT DOCID, GETDATE(), "N" FROM DOCS
WHERE Transnum = (SELECT Inserted.TransNum from Inserted)
したがって、ドキュメントテーブルの前にトランステーブルが更新された場合、トランストリガーの実行にはdocid_syncテーブルに更新が表示されません。この時点で、適切なトランスナム値を持つドキュメントテーブルにエントリがなかったためです。これらの場合、docid_syncテーブルには1つのエントリしかありません。ドキュメントトリガーの結果です。
他の例では、ドキュメントテーブルが最初に更新され、次にトランステーブルが更新されます。これらの例では、docid_syncテーブルには2つのエントリがあります。1つはドキュメントトリガーの結果として、もう1つはトランストリガーの結果です。
他のヒント
両方のトリガーで、トリガーは特定の列が更新された場合にのみdocid_syncテーブルを挿入しています。ストアドプロシージャがトリガー内の列の1つを更新していることを確認してください。トリガーは、トリガーコールからの再帰的な更新である場合、呼び出されませんが、ここではそうではないようです。
もう1つの可能性は、呼び出しトランザクションがセットトリガーオフコマンドでトリガーを無効にした場合です。ストアドプロシージャがトリガーチェックの列の1つを更新していることを確認することから始めます。
もう1つの質問:同じ行が2回更新されています。インラインSQLとエラーケースのストアドプロシージャで、または2つの異なる行を更新していますか?