2010-03-01 5 views
7

Oracle 데이터베이스에서 (최대 1000000 개까지) sql 문을 실행해야합니다. 이러한 명령문은 결과적으로 일관성있는 상태를 가져야하며 오류가 발생하면 모든 명령문을 롤백해야합니다. 이 진술은 참조 순서가 아닙니다. 따라서 외래 키 제약 조건이 활성화 된 경우 문 중 하나가 외래 키 위반을 유발할 수 있습니다.이 위반은 나중에 실행될 문으로 수정됩니다.자율 트랜잭션의 Oracle DDL

먼저 외래 키를 사용하지 않도록 설정하고 모든 문이 실행 된 후에 사용하도록 설정했습니다. 실제 외래 키 위반이 있었을 때 롤백 할 수있을 것이라고 생각했습니다. 그러나 나는 오라클의 모든 DDL 문이 커밋으로 시작 했으므로이 방법으로 문을 롤백 할 방법이 없다는 것을 알았습니다. 여기에 외부 키를 비활성화하는 내 스크립트입니다

begin 
    for i in (select constraint_name, table_name from user_constraints 
      where constraint_type ='R' and status = 'ENABLED') 
    LOOP execute immediate 'alter table '||i.table_name||' disable constraint 
          '||i.constraint_name||''; 
    end loop; 
end; 

몇 가지 조사 후, 나는 그것이 자율 트랜잭션에서,이 경우처럼, DDL 문을 실행하는 것이 좋습니다 것을 발견했다. 그래서 자율 트랜잭션에서 DDL 문을 실행하려고했습니다. NOWAIT가 나는 주요 트랜잭션이 여전히 테이블에 대한 DDL 잠금을 가지고 있기 때문에이 추측하고

을 지정 바쁜 자원 및 취득 :

ORA-00054 :이 다음과 같은 오류가 발생했습니다.

여기에 뭔가 잘못하고 있습니까? 아니면이 시나리오를 작동시키는 다른 방법이 있습니까?

답변

8

몇 가지 접근법이 있습니다.

먼저 고려해야 할 사항은 테이블 수준에서 수행하는 모든 작업이 해당 테이블을 사용하는 모든 세션에 적용된다는 것입니다. 해당 테이블에 대해 독점적 인 액세스 권한이없는 경우 제약 조건을 삭제/다시 작성하거나 비활성화/비활성화하는 것을 원하지 않을 것입니다.

두 번째로 고려해야 할 사항은 백만 삽입/업데이트를 롤백하는 위치에 서기를 원하지 않는다는 것입니다. 롤백은 느릴 수 있습니다.

일반적으로 임시 테이블에로드됩니다. 그런 다음 임시 테이블에서 대상 테이블로 단일 INSERT를 수행하십시오. 단일 명령문으로서 Oracle은 모든 점검 제한 조건을 끝에 적용합니다.

임시 테이블 (예 : 기존 데이터 업데이트)을 실행할 수없는 경우 시작하기 전에 제약 조건 deferrable initially immediate을 만듭니다. 그런 다음 세션 내에서

SET CONSTRAINTS emp_job_nn, emp_salary_min DEFERRED; 

변경 사항을 적용하고 커밋 할 때 제약 조건이 유효화됩니다.

위반을 유발하는 행을 식별하는 데 도움이 될 수 있으므로 DML error logging으로 문의하십시오.

+0

"SET CONSTRAINTS"트릭에 대해 알아 냈고 여기에 나와 내 질문에 답변했습니다. 나는 대답을 보았습니다 :). 고맙습니다. – swamplord

관련 문제