私はこれに対する答えを探してみましたが、実際には何も役に立つとは思えませんでした。あるいは私の検索機能がうまくいかなかったのです。とにかく、ここに私の状況です:
Z_TESTとZ_TEST2という2つの同一のテーブルがある場合があります。必要に応じて監査テーブルをZ_TEST2と呼びます。
どちらもID(number)とCFIELD(CLOB)の2つの列を持っています。 Z_TESTには、Z_TEST2を挿入または更新するトリガがあります(実際にはCLOBフィールドのみ)。
シナリオ1:
通常のトリガーであるZ_TESTで次のトリガーを作成すると、監査テーブルも更新されます。
CREATE OR REPLACE TRIGGER Z_TEST_TRIG
AFTER INSERT OR UPDATE ON Z_TEST
FOR EACH ROW
Begin
If inserting then
Begin
insert into Z_TEST2 values(:new.ID, :new.CFIELD);
end;
end if;
if updating then
begin
update Z_TEST2 Set CFIELD = :new.CFIELD where ID = :new.id;
end;
end if;
End;
シナリオ2:
複合トリガーである次のトリガーを作成し、その "After each row"ブロックを利用すると、監査テーブルのCLOBは何も更新されず、nullになります。
create or replace trigger Z_TEST_TRIG
FOR UPDATE OR INSERT ON Z_TEST
COMPOUND TRIGGER
AFTER EACH ROW IS
Begin
If inserting then
Begin
insert into Z_TEST2 values(:new.ID, :new.CFIELD);
end;
end if;
if updating then
begin
update Z_TEST2 Set CFIELD = :new.CFIELD where ID = :new.id;
end;
end if;
END AFTER EACH ROW;
END Z_TEST_TRIG;
これがなぜうまくいくのか誰にもわかりませんシナリオ1ではなく2私たちのWHOLEフレームワークはシナリオ2(複合トリガー)に基づいていますが、CLOBデータ型を使用する必要性に遭遇したのはごく最近のことですが、それに伴ってこの問題が生じました。
なぜ違いがあり、私のコードに何かが欠けているのですか?
回答:
回答№1は2この問題を解決する時間がないので、変数を使用して解決しました。
宣言内でCLOB変数を宣言するセクション内で:BEFORE EACH ROWまたはAFTER EACH ROWのいずれかで:new.clob_fieldの値を割り当て、トリガー内で:new.clob_fieldではなくinsert / updateステートメントで変数を使用することで、この問題を解決できます。
私はこれと戦っている人々(特に単純なトリガーではなく複合的なトリガー)がたくさんの投稿に出くわしたので、私がこれに費やした時間が他の誰かに役立つと彼らの時間を節約することを願っています。
誰かが私の正気に本当に役立つでしょうその理由を知っているこの記事に遭遇します。new.clob_fieldは、各行セクションのBEFORE / AFTERの挿入/更新ステートメントで使用されると、複合トリガー内でその値を失います。私の心にとらわれたこの考えで、ある日死ぬことはひどいでしょう…
私はまたこれがBLOBにもうまくいくと仮定します(それが問題を引き起こす場合)。
回答№2の場合は1
このような何か....あなただけのupdate句を追加する必要があります
CREATE OR REPLACE TRIGGER after_row_insert
AFTER INSERT
ON Z_TEST
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
Begin
insert into Z_TEST2 values(:new.ID, :new.CFIELD);
End;