데이터베이스 연구실.log

호출 오류와 실행 제약

PLS-00221, ORA-06503, PLS-00306과 ORA-04092의 호출 조건 및 사용자 정의 오류 예제

PLS-00221ORA-06503PLS-00306ORA-04092RAISE_APPLICATION_ERROR-20000~-20999VALID컴파일

#핵심 요약

오류 발생 조건
PLS-00221 함수를 EXEC f_tax(2500)처럼 프로시저로 단독 실행
ORA-06503 함수가 RETURN 없이 끝나는 경로로 실행됨
PLS-00306 프로시저 인자의 개수, 타입이 틀림(이름만 있음)
ORA-04092 트리거 안에서 COMMIT
ORA-20xxx RAISE_APPLICATION_ERROR로 낸 사용자 오류
번호는 -20000 ~ -20999

반환이 빠진 경로가 있는 함수도 컴파일은 VALID로 통과하고, 실행해 봐야 오류가 남
INVALID 0건 점검만으로는 이런 함수를 못 잡으므로, 이행 뒤에는 함수를 실제 데이터로 한 번씩 호출해 보는 검증이 필요함

#개념과 동작 원리

PLS-00306은 호출을 서브프로그램 선언과 맞추지 못한 상황이며 이름, 인자 수, 타입, 선언 위치를 함께 확인함

실습 비교표에 따르면 프로시저 안의 COMMIT은 설계에 따라 넣을 수 있지만, SELECT 안에서 부르는 함수와 트리거 안에서는 COMMIT할 수 없음
트리거의 경우 트리거가 한 일이 사용자 DML과 같은 트랜잭션이기 때문임(변경 이력과 입력값 처리)

#주요 용어와 구성 요소

구문 의미
컴파일 상태와 경고 VALID와 경고 없음은 같은 조건이 아니며 반환 경로 누락은 PLW-05005 대상임
호출 제약 SQL에서 부르는 함수의 부수 효과와 일반 PL/SQL 호출의 허용 범위는 다름

#필수 명령어 또는 SQL

항목 실행 조건
작업 대상 f_tax 호출, f_bad 생성, 조회, 삭제, 사용자 정의 오류
필요 권한 다른 소유자의 함수 호출은 EXECUTE 권한, 자기 스키마 함수 생성은 CREATE PROCEDURE와 테이블 조회 조건 필요
바꿀 입력값 함수명, 인수, 테이블명과 사용자 오류 번호, 메시지
결과 해석 기존 오류 주석만 실습 기록으로 유지하며 PLS-00306 재현 결과, 컴파일 경고 출력은 기재 없음

#함수를 EXEC로 단독 실행

SQL*Plus (객체 소유 계정)조회만 함
EXEC f_tax(2500)
-- 결과: PLS-00221: 'F_TAX' is not a procedure or is undefined

결과 해석:

함수는 EXEC :v_tax := f_tax(2500)처럼 결과를 받을 곳과 함께 부름

#반환이 빠진 함수

SQL*Plus (객체 소유 계정)객체 또는 설정을 변경함
CREATE OR REPLACE FUNCTION f_bad (p_sal IN NUMBER)
RETURN NUMBER
IS
BEGIN
  IF p_sal >= 3000 THEN
    RETURN 1;
  END IF;                 -- 3000 미만이면 RETURN 없이 끝남
END;
/
SQL*Plus (객체 소유 계정)조회만 함
SELECT object_name, status FROM user_objects WHERE object_name = 'F_BAD';   -- 결과: VALID

SELECT ename, sal, f_bad(sal) FROM emp_t;
-- 결과: ORA-06503: PL/SQL: Function returned without value
SQL*Plus (객체 소유 계정)데이터 또는 파일을 삭제함, 되돌릴 수 없음
DROP FUNCTION f_bad;

결과 해석: 급여 3000 이상인 행은 1을 돌려주지만, 3000 미만인 행에서 RETURN 없이 끝나 오류가 남
컴파일 때 경고가 나오는지는 기재 없음

#사용자 정의 오류

예제의 사용자 오류 번호: p_raise_sal의 -20601(사원 없음), 급여 상한 트리거의 -20602, 삭제 차단 트리거와 커미션 상한 트리거의 -20603
같은 번호를 두 트리거가 함께 써서 메시지로만 구분됨

PL/SQL 블록 안조회만 함
RAISE_APPLICATION_ERROR(-20601, p_empno || '번 사원이 없습니다.');

결과 해석:

전체 예는 IN과 OUT 매개변수와 BEFORE와 AFTER 트리거에 있음

#구문과 옵션 설명

PLSQL_WARNINGS로 경고 활성화, 비활성화와 특정 경고의 오류 취급을 정할 수 있음
SQL에서 호출하는 함수는 일반적으로 COMMIT 등 트랜잭션 제어를 할 수 없으며 자율 트랜잭션은 별도 규칙임
일반 트리거도 트랜잭션 제어를 할 수 없고 자율 트리거만 예외임
RAISE_APPLICATION_ERROR의 메시지는 최대 2048바이트이며 세 번째 인수 TRUE는 오류 스택에 추가, 기본 FALSE는 기존 스택을 교체하는 동작임

#사용 조건과 주의사항

실습에서는 이행 후 점검으로 INVALID 객체 0건 확인에 더해 함수의 실제 호출 검증을 권했음
이행 검증 절차 전체는 데이터 이행과 적재 분야에서 다룸

반환 경로, 인자 타입, 자율 트랜잭션 여부를 실제 호출 문맥별로 확인함
경고 출력을 끈 상태에서는 경고가 있어도 보이지 않을 수 있음

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기