これが失敗するのを見るつもりであり、APCのポイントから何も奪わないように見えるという理由だけで、これはbefore
である限り、一見機能しているように見えます。 トリガー:
create table t42 (id number);
create trigger trig42
before insert or update on t42
for each row
declare
c number;
begin
if :new.id is null then
raise_application_error(-20001, 'ID is null');
end if;
select count(*) into c from t42 where id = :new.id;
if c > 0 then
raise_application_error(-20002, 'ID is not unique');
end if;
end;
/
コンパイルされ、データを挿入すると、希望どおりの動作が得られます。
insert into t42 values (1);
1 rows inserted.
insert into t42 values (1);
Error starting at line 20 in command:
insert into t42 values (1)
Error report:
SQL Error: ORA-20002: ID is not unique
ORA-06512: at "STACKOVERFLOW.TRIG42", line 9
ORA-04088: error during execution of trigger 'STACKOVERFLOW.TRIG42'
insert into t42 values (null);
Error starting at line 22 in command:
insert into t42 values (null)
Error report:
SQL Error: ORA-20001: ID is null
ORA-06512: at "STACKOVERFLOW.TRIG42", line 5
ORA-04088: error during execution of trigger 'STACKOVERFLOW.TRIG42'
select * from t42;
ID
----------
1
それはあなたが望むことをするようです。ただし、複数のセッションがある場合はそうではありません。私はこのセッションに参加していません。別のセッションで私ができること:
insert into t42 values (1);
1 row created.
select * from t42;
ID
----------
1
1 row selected.
うーん、それは奇妙です。まあ、それは延期されているかもしれません...両方をコミットしましょう:
commit;
select * from t42;
ID
----------
1
1
2 rows selected.
おっとっと。一度セッションが別のセッションのコミットされていないデータを見ることができないので、これは決して機能しません。
また、1つのステートメントに複数の行を挿入すると、テーブルの変更の問題が発生します。
SQL> insert into t42 select level+1 from dual connect by level <= 5;
insert into t42 select level+1 from dual connect by level <= 5
*
ERROR at line 1:
ORA-04091: table STACKOVERFLOW.T42 is mutating, trigger/function may not see it
ORA-06512: at "STACKOVERFLOW.TRIG42", line 7
ORA-04088: error during execution of trigger 'STACKOVERFLOW.TRIG42'
SQL>
ダブルおっと。
after
でも トリガーとパッケージがテーブルの変更の問題を回避する場合でも、挿入または更新のたびにテーブル全体をロックしない限り、この問題は発生します(私は思います)。 APCが言ったように、制約はこのレベルではなく、データベースの奥深くに実装されています。
複数のセッションがある場合は違います。また、1つのセッション内であっても、列にインデックスがない限り、パフォーマンスはcount(*)
としてスケーリングされません。 徐々に遅くなります。そして、もしあなたがインデックスを持っているなら、そもそもそれをユニークなインデックスにしてみませんか?
最後に、トリガー設計ガイドライン から :