저장 프로시저 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 을 사용 하면 오류 가 발생 하지 않 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
자바 작업 은 Clob 또는 NClob 데이터 형식의 저장 프로 세 스 인 스 턴 스 를 포함 합 니 다.텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.