좋아요. 첫째, SELECT INTO ...로 NO_DATA_FOUND 예외를 발생시킬 위험이 있습니다.이 예외를 발생 시키면 전체 삽입이 삭제됩니다. 두 번째로 예외를 제기하면 전체 삽입이 중단됩니다.
은 예외를 발생시키지 않고 차단 된 표에있는 ID를 무시하십시오. 원래 아이디어를 따르려면 한 가지 방법은 아무것도 발견되지 않으면 NO_DATA_FOUND 예외를 사용하여 삽입하는 것입니다. 나는 당신의 테이블에 뷰를 만들고 이것에 INSTEAD OF trigger을 정의합니다.
우리가 설정하면 테스트 환경을 내가
(아래 참조)하지만이 방법을 사용하지 않을
:
SQL> create or replace view v_tmp_test as select * from tmp_test;
View created.
SQL> create or replace trigger tr_test
2 instead of insert on v_tmp_test
3 for each row
4
5 declare
6
7 l_id tmp_test.id%type;
8
9 begin
10
11 select id into l_id
12 from tmp_blocked
13 where id = :new.id;
14
15 exception when no_data_found then
16 insert into tmp_test values (:new.id);
17 end;
18/
Trigger created.
SQL> show error
No errors.
SQL> insert into v_tmp_test
2 select level
3 from dual
4 connect by level <= 3;
3 rows created.
SQL> select * from tmp_test;
ID
----------
1
2
:
SQL> create table tmp_test (id number);
Table created.
SQL> create table tmp_blocked (id number);
Table created.
SQL> insert into tmp_blocked values (3);
1 row created.
는 그런 다음 사용할 수 있습니다 내가 말했듯이, 나는 트리거를 사용하지 않을 것입니다. 더 효율적인 방법은 MERGE을 사용하는 것입니다. 위와 동일한 설정을 사용하십시오. 데이터 무결성이 정말로 무엇을하지 않습니다 -
SQL> merge into tmp_test o
2 using (select a.id
3 from (select level as id
4 from dual
5 connect by level <= 3) a
6 left outer join tmp_blocked b
7 on a.id = b.id
8 where b.id is null
9 ) n
10 on (o.id = n.id)
11 when not matched then
12 insert values (n.id);
2 rows merged.
SQL>
SQL> select * from tmp_test;
ID
----------
1
2
이보다 쉽게 대안은 그냥 내가 정말이 방법으로 트리거의 사용 및 오류를 싫어하는 MINUS
insert into tmp_test
select level
from dual
connect by level <= 3
minus
select id
from tmp_banned
출처
2013-03-06 11:27:29
Ben