읽기

2012-10-24 2 views
1

나는 세 개의 테이블을 가지고 : A와 B 는 관계가 많은 B를 가질 수있다 그래서 B는 열 중 하나로서 A.id에 대한 참조가읽기

Table A 
|id|date|... 

Table B 
|id|A_id|... 

테이블 A에 오라클 트리거를 생성하여 업데이트 될 때 A_Mod 테이블을 업데이트하도록했습니다.

이 트리거는이 테이블 B에 대한 트리거를 만드는 좋은 :)

내 문제시 작동

CREATE OR REPLACE TRIGGER TR_A_INSERT_UPDATE 
AFTER INSERT OR UPDATE ON A 
FOR EACH ROW 
BEGIN 
    INSERT INTO A_Mod values(..., :new.date, ...) 
END; 

입니다

트리거는 다음과 같습니다

CREATE OR REPLACE TRIGGER TR_B_INSERT_UPDATE 
    AFTER INSERT OR UPDATE ON B 
    FOR EACH ROW 
    DECLARE 
     ts TIMESTAMP; 

    BEGIN 
    SELECT aa.date INTO ts FROM B bb 
     INNER JOIN A aa ON a.id = bb.A_id 
     WHERE bb.id = :new.id; 

     INSERT INTO A_Mod values(..., :new.date, ...) 
    END; 

이 트리거 테이블 B에서 업데이트 된 라인의 ID를 읽은 다음 해당 포인트에서 날짜를 가져 오는 중입니다. 테이블 A에 땡 행은 그 다음

A_Mod

에 삽입하려고 문제 나는 내가 FOR EACH ROW 라인을 제거하고함으로써이 오류를 제거 할 수 docs 보면

Error report: 
SQL Error: ORA-04091: table B is mutating, trigger/function may not see it 
ORA-06512: at "TR_B_INSERT_UPDATE", line 5 
ORA-04088: error during execution of trigger 'TR_B_INSERT_UPDATE' 
04091. 00000 - "table %s.%s is mutating, trigger/function may not see it" 
*Cause: A trigger (or a user defined plsql function that is referenced in 
      this statement) attempted to look at (or modify) a table that was 
      in the middle of being modified by the statement which fired it. 
*Action: Rewrite the trigger (or function) so it does not read that table. 

돌연변이 오류를 얻을 수있다 명령문 당 한 번씩 발동하지 말고 한 번에 한 번씩 발사하십시오. 불행히도 ORM 매퍼를 사용하고 있으므로 업데이트가 어떻게 이루어지는 지 제어하지 마십시오. 업데이트가 여러 행을 처리 할 때가있을 것이라고 생각합니다.

문서는 임시 테이블을 만드는 것에 대해 말하고 있지만 어떻게 도움이 될지 모르겠습니다. 트리거 내에서 임시 테이블을 만들고이 임시 테이블에서 트리거를 생성하여 A_Mod를 업데이트하고 트리거가 시작되면이 임시 테이블을 업데이트 한 다음 모든 것을 삭제해야합니까?

모든 도움말을 크게 높이 셨습니다.

감사

답변

2

B 테이블을 조회하는 B에 트리거의 모든 이유가 있다고 표시되지 않습니다. 당신은 필요한 자식 테이블에 트리거가 부모 테이블에서 모든 정보를 조회하거나 삽입 할 경우, 나는 매우 걱정 것, 단순히 데이터 모델링 관점에서 :new.a_id

CREATE OR REPLACE TRIGGER TR_B_INSERT_UPDATE 
    AFTER INSERT OR UPDATE ON B 
    FOR EACH ROW 
DECLARE 
    ts TIMESTAMP; 
BEGIN 
    SELECT a.date 
    INTO ts 
    FROM A a 
    WHERE a.id = :new.a_id; 

    INSERT INTO A_Mod values(..., :new.date, ...) 
END; 

를 사용하여 A를 조회 할 수 있어야한다 데이터를 부모 테이블이 기록하는 동일한 기록 테이블에 저장합니다. 그게 정상화 문제를 나타내는 것 같습니다.

+0

위대한 작품 - 감사합니다! – RNJ