2011-11-17 3 views
2

동일한 테이블에 새 레코드를 삽입하려는 테이블에 새 레코드를 삽입 할 때 트리거가 작동합니다.
내 트리거는 다음과 같습니다동일한 테이블에 레코드를 삽입하기위한 INSERT 트리거

create or replace trigger inst_table 
after insert on test_table referencing new as new old as old 
for each row 
declare 
     df_name varchar2(500); 
     df_desc varchar2(2000); 

begin 
     df_name := :new.name; 
     df_desc := :new.description; 

    if inserting then 
      FOR item IN (SELECT pid FROM tbl2 where pid not in(1)) 
      LOOP 
       insert into test_table (name,description,pid) values(df_name,df_desc,item.pid); 
      END LOOP;  
    end if; 
end; 

는 내가이 같은 테이블에 삽입 할 저를 방해하는 생각

ORA-04091: table TEST_TABLE is mutating, trigger/function may not see it

같은 오류를 제공합니다.
그래서이 새 레코드를 동일한 테이블에 삽입 할 수 있습니다.

참고 : - 나는 데이터베이스로 오라클을 사용하고 돌연변이 당신이 트리거하고있는 테이블을 수정하는 행 수준 트리거를 가지고있는 시간을 발생

+1

[Oracle 트리거 - 테이블 변경 문제] 가능한 복제본 (http://stackoverflow.com/questions/2138363/oracle-triggers-problem-with-mutating-tables) – APC

답변

10

. 문제는 오라클이 어떻게 행동해야하는지 알 수 없다는 것입니다. 행을 삽입하고 트리거 자체가 행 테이블에 삽입되고 오라클이 혼란스러워하므로 트리거로 인해 테이블에 삽입됩니다. 트리거 조치가 적용됩니까?

이 솔루션은 3 단계 프로세스입니다.

1. 삽입 될 행을 추적하는 패키지를 인스턴스화하는 트리거 이전의 명령문 레벨.

2.) 이전 단계에서 인스턴스화 한 패키지 변수에 해당 행 정보를 저장하는 트리거 이전 또는 이후의 행 수준.

3.) 테이블에 삽입하는 트리거 이후의 명령문 레벨, 패키지 변수에 저장된 모든 행.

이의 예는 여기에서 찾을 수 있습니다 : 도움이

http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936

희망을.

+0

감사 정보 - FYI에게 물어보십시오 톰 링크가 끊어졌습니다. :) –

1

나는 이것을 달성하기 위해 트리거 이외의 다른 방법을 찾아야한다고 말하고 싶습니다. Mark Bobak의 대답에서 언급했듯이 트리거는 행을 삽입 한 다음 트리거에 의해 삽입 된 각 행에 대해 더 많은 행을 삽입하기 위해 트리거를 호출해야합니다.

삽입 프로 시저를 작성하거나 값이 아닌 하위 쿼리를 통해 삽입하는 방법을 살펴 보겠습니다.

트리거는 간단한 문제를 해결하는 데 사용할 수 있지만 더 복잡한 문제를 해결할 때 두통을 유발합니다.

APC가 게시 한 duplicate question에 대한 답변과 함께 Tom Kyte의 this article도 읽을 가치가 있습니다. BTW, 기사도 중복 질문에서 참조하지만 링크가 지금 구식입니다.

1

나쁜 트리거가 얼마나 나쁜지 불평 한 후에도 여기에 또 다른 해결책이 있습니다.

어쩌면 두 개의 테이블이 있어야합니다. 현재 수행중인 것처럼 데이터를 test_table 테이블에 삽입하십시오. 그러나 트리거가 test_table 테이블에 추가 행을 삽입하는 대신 데이터가있는 세부 테이블을 가져야합니다.트리거는 필요한 모든 행을 상세 테이블에 삽입 할 수 있습니다.

두 테이블간에 계단식 외래 키 관계를 삭제하면 돌연변환 트리거 오류가 다시 발생할 수 있으므로이를 방지하는 것이 가장 좋습니다.

+0

오라클 트리거에 대한 생각과 동의합니다. 그것들은 농담이었고 나는 사건 중심의 개발 방법론으로 생각할 때 심하게 착각했다. 비즈니스 로직에서는 트리거가 아무 쓸모가 없습니다. –

관련 문제