저장 프로시저 ORA - 4068 의 오류 분석!

다음은 하나의 예 로 오 류 를 분석 합 니 다.
SQL> conn /as sysdba
   。
SQL> grant create any table to u1;

    。

SQL> conn u1/u1
   。
SQL> create table t as select * from t1;

    。

SQL> create or replace procedure p_recreate as
  2   begin
  3    execute immediate 'drop table t purge';
  4    execute immediate 'create table t as select * from t1';
  5  end;
  6  /

     。

SQL> create or replace procedure p_insert as
  2   begin
  3     insert into t select * from t;
  4     commit;
  5  end;
  6  /

     。

SQL> begin
  2    p_recreate;
  3    p_insert;
  4  end;
  5  /
begin
*
  1      :
ORA-04068:              
ORA-04065:    ,        stored procedure "U1.P_INSERT"
ORA-06508: PL/SQL:          : "U1.P_INSERT"      
ORA-06512:   line 3

위 에 두 가지 과정 을 세 웠 습 니 다. 첫 번 째 과정 에서 precreate 에 서 는 동적 구문 drop table t purge 를 통 해 동적 구문 create table t as select * from t1 을 통 해 t 표를 재 구축 합 니 다.두 번 째 과정 pinsert 는 t 표 의 내용 에 따라 자체 복 제 를 실현 하 는 것 이 더 간단 하 다.
두 개의 저장 과정 을 같은 익명 의 빠 른 속도 로 호출 하면 위의 ORA - 04068 오류 가 발생 합 니 다.만약 두 과정 을 단독으로 집행 한다 면 잘못 보고 하지 않 을 것 이다.
SQL> exec p_recreate;

PL/SQL        。

SQL> exec p_insert;

PL/SQL        。
이 ORA - 04068 오 류 를 보고 가장 먼저 생각 나 는 것 은 precreate 프로 세 스 가 시 계 를 삭제 하고 재 구축 하 는 작업 을 하면 이 t 표 와 관련 된 모든 저장 과정 이 invalid 상태 로 변 할 수 있 습 니 다.다음 과 같다.
SQL> exec p_recreate;

PL/SQL        。

SQL> select OBJECT_NAME,STATUS from user_objects where OBJECT_NAME like 'P_%';

OBJECT_NAME     STATUS
--------------- -------
P_RECREATE      VALID
P_INSERT        INVALID
t 표 구조 가 재건 축 전에 변화 가 없 기 때문에 간단 한 컴 파일 을 통 해 pinsert 프로 세 스 의 상태 가 valid 로 변 합 니 다.다음 과 같다.
SQL> exec p_recreate;

PL/SQL        。

SQL> alter procedure p_insert compile;

     。

SQL> select OBJECT_NAME,STATUS from user_objects where OBJECT_NAME like 'P_%';

OBJECT_NAME     STATUS
--------------- -------
P_RECREATE      VALID
P_INSERT        VALID

따라서 호출 전에 p 를 재 편집 하려 고 시도 합 니 다.insert 과정:
SQL> begin
  2    p_recreate;
  3    execute immediate 'alter procedure p_insert compile';
  4    p_insert;
  5  end;
  6  /
begin
*
  1      :
ORA-04068:              
ORA-04065:    ,        stored procedure "U1.P_INSERT"
ORA-06508: PL/SQL:          : "U1.P_INSERT"      
ORA-06512:   line 4
오류 가 여전 하고 재 미 있 는 것 은 오류 로 인해 호출 pinsert 과정 중, 그래서 alter procedure pinsert copile 명령 은 분명히 실행 되 었 고 성공 적 이 었 습 니 다.이 명령 의 실행 성공 설명 pinsert 프로 세 스 의 상태 가 valid 상태 로 회복 되 었 지만 오류 가 발생 했 습 니 다.
SQL> begin
  2    p_recreate;
  3    execute immediate 'begin p_insert; end;';
  4  end;
  5  /

PL/SQL        。
동적 sql 방식 으로 p 호출insert 과정 은 잘못 보고 하지 않 습 니 다.문 제 는 이미 명확 해 졌 지만, 분명하게 말 하려 면 처음부터 말 해 야 한다.
저장 프로 세 스 는 컴 파일 할 때 문법 오류, 권한 이 모든 대상 의 의존성 을 자동 으로 검사 합 니 다.그리고 실 행 될 때 Oacle 은 비슷 한 검 사 를 하지 않 고 직접 실행 과정 을 하 는 것 도 저장 과정 이 비교적 효율 적 인 원인 중 하나 이다.
저장 프로 세 스 가 의존 하 는 대상 에 변화 가 생 겼 을 때 Oacle 은 저장 프로 세 스 의 상 태 를 invalid 로 자동 으로 설정 하고 저장 프로 세 스 의 상태 가 invalid 라면 다음 에 실 행 될 때 재 컴 파일 을 시도 합 니 다. 컴 파일 이 통과 되면 실 패 했 을 때 오류 가 발생 합 니 다.
이것 이 바로 위의 예 에서 두 개의 저장 과정 이 단독으로 집행 되 는 것 이 잘못 보고 되 지 않 는 원인 이다.비록 precreate 과정 은 표 t 를 재 구축 하고 pinsert 프로 세 스 실효, 하지만 pinsert 는 호출 할 때 재 컴 파일 을 시도 합 니 다. t 표 의 구조 가 변 하지 않 기 때문에 컴 파일 이 잘못 되 지 않 습 니 다. 따라서 pinsert 호출 은 틀 리 지 않 습 니 다.
그렇다면 왜 두 과정 을 함께 놓 고 실행 하면 잘못 보고 하고 재 번역 을 시도 해도 소 용이 없 을 까?이것 은 pinsert 실효 과정 은 p 호출insert 과정의 익명 블록 에서익명 블록 을 Oacle 에 제출 할 때 Oacle 은 모든 과정의 상 태 를 검사 하 였 으 며, 이 로 인해 pinsert 실효 precreate 과정 이 아직 실행 되 지 않 았 기 때문에 모든 과정의 상 태 는 정상 입 니 다.그래서 Oacle 은 과정의 상태 정 보 를 기록 하고 호출 과정 을 시작 했다.호출 중 precreate 과정 후 t 표 가 삭제 되 어 재 구축, pinsert 의 상태 가 변 했 지만, 이때 oracle 대 pinsert 검사 가 완료 되 었 기 때문에 p 를 직접 실행 하려 고 시도 합 니 다.insert 코드 발견 pinsert 의 상태 가 바 뀌 었 기 때문에 ORA - 04068 을 잘못 보 고 했 습 니 다.
같은 이치, p 에 도insert 를 재 컴 파일 했 습 니 다. Oacle 이 실 행 했 을 때 검사 할 때 코드 가 바 뀌 었 습 니 다. 현재 pinsert 와 호출 시의 pinsert 는 이미 변화 가 생 겼 기 때문에 오류 가 발생 할 수 있 습 니 다. 비록 이때 저장 과정의 상태 가 이미 정상 적 이 더 라 도.
동적 sql 을 사용 하여 잘못 보고 하지 않 는 이 유 는 더욱 쉽게 이해 할 수 있 습 니 다.동적 sql 문 구 를 사용 하여 Oacle 은 컴 파일 할 때 진행 하 는 작업 을 실행 할 때 까지 연기 합 니 다. 즉, Oacle 은 p 를 호출 합 니 다.recreate 후 p 호출insert 과정 전 pinsert 를 검사 하고 재 컴 파일 하기 때문에 동적 sql 을 사용 하면 오류 가 발생 하지 않 습 니 다.

좋은 웹페이지 즐겨찾기