2009-08-26 7 views
0

私はテーブルを持っています[MYTABLE]と挿入、更新トリガーです。他のコードを呼び出す前にT-SQLトリガーの効果を変更

トリガーは、[MYTABLE]の変更に基づいていくつかの作業を実行するストアドプロシージャを実行する必要があります。ストアドプロシージャのコードをトリガに移動することはできません。トリガーは変更が行われた後を実行するので

はこれまでのところ、とても良い...、ストアドプロシージャは[挿入]または[削除]メタテーブルにアクセスする必要がありません。

しかし...トリガがつの追加フィールド[LastModifiedの】 SMALLDATETIME)を変更する必要があるので、ストアドプロシージャは、その処理中にそのデータを使用することができます。これはではなくであるため、ストアドプロシージャは挿入/更新されたものを見ることができます。プロシージャは、それをトリガする更新に含まれていない他のレコードに基づいていくつかの処理を行います。かつてので - 私のトリガーは、(私は再帰的トリガーがオフになっている場合)、またはそれが二回ストアドプロシージャを呼び出すことになりますすべての何もしませんどちらか[LastModifiedの]を、変更した場合

問題は、あります私の変更のために再び[LastModified]に変更されました。 (a)は[LastModifiedの]は、各変更で更新されますと、(b)ストアドプロシージャのみ後に呼び出され、私はこれを回避することができますので、それはは[LastModifiedの] の新しい値へのアクセスを持っているどのように

私は考えている2つのアイデアがありますが、彼らは面白いにおいがするので、より簡単な解決策があるかどうかを知りたいと思います。

編集:

1. 2つのトリガー:

[OK]を、ここで私はこれまでのところ、多分議論をするのに役立ちますしている溶液です。 "INSTEAD OF"トリガーはユーザーのレコードの更新を処理し、LastModifiedを変更しますが、更新がから SP(変更された列に基づいて判断できます)になるとすぐに戻ります。もう1つはEXECを呼び出す "AFTER"トリガーです。このトリガーは、LastModified列が既にに適用された更新をINSTEAD OFトリガーで取得します。少なくとも私はそれがどのように機能するのかと期待しています。

2. ModifiedDateを別のテーブルに移動します。このようにして、ユーザーがINSERT/UPDATEを開始し、監査レコードを別のテーブルに追加してSPを呼び出す場合、のみのAFTER INSERT/UPDATEトリガーを1つ作成できます。 SPは他のレコードを変更し、トリガを再び発動させるが、それ以上の作業をせずにすぐに状況を認識して戻ります。

最初の解決策の欠点は、トリガで列リストを維持する必要があるため、INSTEAD OF更新が実際に作業を意図しているためです(リストに列を追加したのでINSERT INTO tbl FROMを挿入すると、列を指定する必要があります)。

+0

最初のINSERT/UPDATEはどのように実行されますか?そしてあなたはトリガを使用する必要がありますか?私が尋ねる理由は、イベントの全過程が(トリガを必要とせずに)ストアドプロシージャ内にカプセル化できるということです。 –

答えて

3

IF UPDATE(LastModified)命令を試したことがありますか?

CREATE TRIGGER XYZ ON MYTABLE 
FOR INSERT, UPDATE 
AS 
BEGIN 
IF UPDATE(LastModified) 
    RETURN 
ELSE 
    BEGIN 
    UPDATE MYTABLE SET LastModified = GETDATE() 
    FROM MYTABLE INNER JOIN INSERTED ON MYTABLE.ID = INSERTED.ID 
    EXEC TheStoreProc 
    END 
END; 
+0

これは、ワークフローの間違った側でEXECが呼び出されるという問題を解決しますが、実際にはLastModifiedを変更しません。これは、トリガーによって更新する必要があります。 – richardtallent

+0

スクリプトを修正しました。テーブルを更新してから、スクリプトを実行します。トリガーは2回トリガーされますが、内部実行は直ちに終了します。 – Rodrigo

+0

Rodrigo--ありがとうございます。しかしこれが終わったら、EXECのLastModifiedを見ますか?それは、何らかの暗黙のトランザクション内でトリガが動作しない限り、それを見ることは意味があります。 – richardtallent

0

私はあなたが説明している流れを理解していません。それは:

  1. レコードが更新され
  2. 更新トリガPROCが呼び出される
  3. トリガアップデートは、トリガーがある限り、正常に動作する必要があります別のprocの

を呼び出し

  • フィールドLASTMODIFIED」別のproc "は同じテーブルを更新しません。 トリガーを再び開始します。

    「別のprocの」が再びテーブルを更新である場合、あなたはおそらく前に「別のPROC」の呼び出しにトリガーにそれらのアップデート を移動することができます。

    それは何ですか?

  • +0

    残念ながら、それはまさに起こっていることです。 SPは*元のトリガーと同じ*レコードを更新することは決してありませんが、他のトリガーは更新されます。だから、再帰のチャンスはありませんが、それでもやはり面倒な小さなワンステップループです。残念なことに、SPコードをトリガーに移動することは効果がありません(SPは*他の*レコードにのみ影響し、INSTEAD OFトリガーはワンステップ再帰を減らさないため)テーブルは同じSPを呼び出します)。私はむしろビューを使用したいが、今度は電話をかけることはできない。 – richardtallent

    関連する問題