これは、パーサが混乱しているように見えるようなものにそれを変更してみてください。 AS ROOT
を完全に削除すると、予期したPLS-00405: subquery not allowed in this context
エラーに戻ります。なぜそれが混乱しているのか分かりません。あなたはそのクエリをスタンドアロンで実行することができます。しかし、あなたがしようとしていることはできないので、あまり心配する価値はないでしょう。
サブクエリにも3つの列があり、複数の行が返されるため、現在の行のスカラーPARENT_IDと比較すると機能しません。サブクエリーを別々に実行して、実際に関心のある値をローカル変数に選択してチェックすることができます。
しかし、あなたは挿入前のトリガーを持っていて、トリガーが反対のテーブルを照会しているので、挿入しようとすると突然のテーブル例外が発生します(または、一度に行)。
私はあなたが達成しようとしているものを理解していれば、あなたの代わりに後のINSERTトリガーを使用することができます。
create or replace trigger check_cycle
after insert or update on departments
declare
l_hascycle pls_integer;
begin
select max(connect_by_iscycle)
into l_hascycle
from departments
start with parent_id is null
connect by nocycle prior id = parent_id;
if l_hascycle = 1 then
raise_application_error(-20000, 'Sorry.');
end if;
end;
/
これは、何のサイクリングがない場合はすべての行に対してゼロになりますCONNECT_BY_ISCYCLE pseudocolumnを、使用していますサイクルする任意の列に対して1つです。そのmax()
を選択してチェックすると、ローカルのl_hascycle
変数に1つの値0または1が設定され、その変数を使用して例外をスローするかどうかを決定できます。最初の新しい行がOKであり、第二のサイクルを引き起こす
ID PARENT_ID NAME
---------- ---------- ------------
1 Test
2 1 Test
...:
insert into departments (id, parent_id, name) values (3, 2, 'OK');
1 row inserted.
insert into departments (id, parent_id, name) values (2, 3, 'Cycles');
ORA-20000: Sorry.
ORA-06512: at "SCHEMA.CHECK_CYCLE", line 11
ORA-04088: error during execution of trigger 'SCHEMA.CHECK_CYCLE'
のような既存の非サイクリングデータの上にテスト行のカップルを挿入
最初の挿入は(まだコミットされていない)効果にまだある、第二は、暗黙的にロールバックされました:
select * from departments:
ID PARENT_ID NAME
---------- ---------- ------------
1 Test
2 1 Test
3 2 OK
これは、start with
句のため、nullの親に達する既存のツリーに接続されていないデータのサイクルをキャッチしません。データを持つexampelの場合は、例外が発生することなく4,5,5,4を挿入することができます.4または5からヌルの親を持つ行へのルートがないためです。しかし、これは別の問題であり、別々にテストしたいことがあります。
他のセッションでコミットされていない変更のデータも表示されないため、2つのセッションが同時に独立して有効な行を挿入する可能性があります。
クエリからすべての "AS"を削除しようとしましたか? – Hawk
もちろん。助けにならない。 –
あなたはどこでも(私が見る限り)使用されていないので、この部分があなたの質問の中で必要とされているのではないかと自分自身に問うべきです。 また、 'new'キーワードの隣にコロンを忘れる必要はありません。 –