2

トリガー(Firebird 2.5)から他のテーブルを更新することは可能ですか(私はそう思います:はい)。たとえば、次のような更新後のトリガーを持つテーブル Xが 1 つあります。

begin
  if  (new.CODE<>old.CODE)  then
  BEGIN
  post_event  'CODE_CHANGE';
  UPDATE Y SET CODE=10 WHERE ID=1;
  END
end

また

begin
  if  (new.CODE<>old.CODE)  then
  BEGIN
  post_event  'CODE_CHANGE';
  EXECUTE STATEMENT ('UPDATE Y SET CODE=10 WHERE ID=1');
  END
end

しかし、うまくいきません (テーブル Yは変化しません)。

トリガーの完全な定義 (理解を深めるため)

SET TERM ^^ ;
CREATE TRIGGER ABC FOR X ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 0 AS
begin
  if  (new.CODE<>old.CODE)  then
  BEGIN
  post_event  'CODE_CHANGE';
EXECUTE STATEMENT ('UPDATE Y SET CODE=10 WHERE ID=1');
  END
  post_event 'CHANGE';
end ^^

そして2番目の問題:UPDATEコマンドにパラメーターを与える方法(テーブル Y)-上記のコードの値「 10 」の代わりに、 new.CODE (テーブル Xからの新しい値)を次のように置きたいということです:

UPDATE Y SET CODE=new.CODE WHERE ID=1

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

アートク

4

1 に答える 1

2

はい、トリガーから任意のテーブルを操作できます。トリガーに関連付けられているテーブルに限定されません。UPDATEでは、問題は、トリガーのステートメントが機能しないのはなぜですか?私は3つの可能性を見ます:

  1. if (new.CODE<>old.CODE) thenステートメント。のいずれかnewまたはold値がであるcode場合NULL、そのthen部分は実行されません。詳細な説明については、FirebirdNullGuideを参照してください。DISTINCTここでの解決策は、演算子を使用することです。もちろん、code値が変更されていない場合、ifステートメントも「失敗」しますが、それは明らかなはずです:)また、CODE_CHANGEイベントを受信した場合は、ifstaementが実行されていることを確認できます。また、マルチアクショントリガーでは、トリガーがによって起動された場合はNEWになり、トリガーがによって起動された場合はOLDになります。NULLDELETENULLINSERT。したがって、トリガーはUPDATEステートメントの場合にのみ期待どおりに機能します。おそらく、それを3つの異なるトリガーに分割したいと思うでしょう。
  2. 更新のwhere一部が失敗します。つまり、テーブルYにID = 1のレコードがありません。考えられる解決策は、UPDATE OR INSERTステートメントを使用することです。
  3. あなたは実際commitに取引をしていますか?ロールバックすると、「メインテーブル」だけでなく、すべてのテーブルの変更がロールバックされます。

2番目の質問の時点で-はい、UPDATEステートメントは問題ないように見えます。任意のステートメントでトリガーコンテキスト変数を使用することは有効です。ステートメントで他の変数の前にコロンを付けることで、それらを使用できます。

UPDATE Y SET CODE = :SomeVariable WHERE ID=1
于 2013-01-31T11:22:41.333 に答える