[ORACLE] PLS-00306 조치 절차

반응형

Oracle PL/SQL 오류 PLS-00306(잘못된 인수 개수 또는 타입) 발생 시, 프로시저/함수 호출 구문을 기준으로 파라미터 타입·개수·순서·NULL 처리·오버로드·명명 인자 사용을 점검하고 복구 및 재발 방지까지 정리합니다

PLS-00306 조치 절차

PLS-00306 조치 절차

오류 PLS-00306
상황 프로시저 호출 에러(인수 개수 또는 타입 불일치)
핵심 호출 구문 ↔ 프로시저 시그니처(파라미터) 1:1 대조
우선순위 오버로드/NULL/명명 인자/암묵적 형변환 여부부터 점검

PLS-00306은 “프로시저/함수 호출이 정의된 파라미터와 맞지 않다”는 신호입니다.
단순히 개수만이 아니라 타입, 순서, IN/OUT 모드, 오버로드(동일 이름 다중 정의), NULL 처리 방식이 복합 원인으로 자주 얽힙니다.
본 문서는 일반오류형(확장형) 흐름으로 점검 → 복구 → 재발 방지를 정리합니다.

개요

PLS-00306 조치의 출발점은 “호출 구문 한 줄”과 “정의(시그니처)”를 정확히 확보하는 것입니다.
특히 운영 환경에서는 동일 프로시저명이 패키지/스키마/시노님/버전에 따라 다른 정의를 참조하는 경우가 있어, 먼저 어떤 객체를 호출하고 있는지부터 확정해야 합니다.

1) 호출 대상 객체 확정(스키마/패키지/시노님/DB 링크 여부)
2) 정의된 파라미터 목록 조회(타입/순서/디폴트/IN·OUT 모드)
3) 호출 인자와 1:1 매핑 점검(개수, 타입, NULL, 오버로드)
4) 수정(명명 인자, 명시적 CAST/TO_*, 변수 선언 타입 정정)
5) 재발 방지(인터페이스 표준화, 변경관리, 컴파일 검증) 적용

환경

항목 기록(예시)
DB Oracle Database (버전 기입 권장)
발생 위치 배치/ETL/애플리케이션/SQL 실행 도구 등
호출 형태 패키지.프로시저(...) 또는 스키마.패키지.프로시저(...)
호출자 타입 익명 블록/트리거/프로시저/애플리케이션(바인드 변수)
최근 변경 프로시저 시그니처 변경, 오버로드 추가, 컬럼 타입 변경, 배포 누락 등
“프로시저 호출 에러”만으로는 원인이 여러 갈래로 분기됩니다.
아래 점검 단계에서 호출 구문과 파라미터 정의를 확보하면 PLS-00306은 대부분 빠르게 정리됩니다.

증상

대표 메시지 패턴은 다음과 같습니다.

PLS-00306: wrong number or types of arguments in call to '프로시저명'
- 동일 프로시저를 특정 데이터/특정 사용자에서만 호출하면 실패하는 경우가 있음
- 개발/운영 DB에서만 재현되는 경우가 있음(정의가 다르거나 시노님이 다르게 걸린 경우)
- NULL을 넘길 때만 실패하는 경우가 있음(오버로드/형변환 모호성)

1차 점검

1차 점검은 “무엇을 호출하고 있는지”와 “정의가 무엇인지”를 빠르게 확인하는 단계입니다.
아래 쿼리는 최소 증빙 세트로 유용합니다.

1) 호출 대상 객체 확정

- 패키지/프로시저가 어느 스키마에 있는지 확인
- 동일 이름의 시노님이 다른 객체를 가리키지 않는지 확인
- 애플리케이션이라면 실제 호출 SQL(바인드 포함)을 확보
-- (예시) 동일 이름 객체가 여러 스키마에 있는지 확인
SELECT owner, object_name, object_type, status
FROM all_objects
WHERE object_name = UPPER('프로시저명')
ORDER BY owner, object_type;

-- (예시) 시노님 확인(동일 이름이 다른 대상으로 매핑되는지)
SELECT owner, synonym_name, table_owner, table_name, db_link
FROM all_synonyms
WHERE synonym_name = UPPER('프로시저명');

2) 파라미터 정의(시그니처) 확인

- all_arguments에서 position/sequence 기준으로 파라미터를 확인
- 패키지 내 프로시저라면 package_name까지 정확히 지정
- IN/OUT 모드, 데이터 타입, 기본값(디폴트) 존재 여부를 함께 확인
-- 단독 프로시저(스키마에 직접 생성된 경우)
SELECT owner, object_name, package_name, argument_name, position, data_type, in_out
FROM all_arguments
WHERE owner = UPPER('스키마명')
  AND object_name = UPPER('프로시저명')
  AND package_name IS NULL
ORDER BY position;

-- 패키지 프로시저인 경우
SELECT owner, object_name, package_name, argument_name, position, data_type, in_out
FROM all_arguments
WHERE owner = UPPER('스키마명')
  AND package_name = UPPER('패키지명')
  AND object_name = UPPER('프로시저명')
ORDER BY position;

3) 호출 구문과 1:1 매핑 체크

- 인자 개수: 정의된 position 수와 호출 인자 수가 동일한지
- 인자 타입: 문자열/숫자/날짜/LOB/레코드/컬렉션 등 정확히 일치하는지
- IN/OUT: OUT 파라미터에 리터럴을 넘기지 않았는지(변수여야 함)
- 디폴트 파라미터: 중간 파라미터를 생략하면 실패할 수 있음(명명 인자 필요)

심화 분석

1차 점검에서 정의와 호출이 “얼추 맞는 것 같은데” 계속 실패한다면, 아래 항목이 주범인 경우가 많습니다.
PLS-00306은 모호성(어떤 오버로드를 선택할지 결정 불가)에서도 발생할 수 있습니다.

원인 유형 자주 나오는 패턴 해결 포인트
오버로드(다중 정의) 동일 프로시저명이 파라미터 조합만 다른 형태로 여러 개 존재 명명 인자 사용 또는 명시적 CAST로 호출 대상을 고정
NULL 인자 NULL을 넘기면 타입 추론이 안 되어 오버로드 선택 실패 CAST(NULL AS 타입) 또는 변수에 타입 선언 후 전달
IN/OUT 모드 오류 OUT 파라미터에 '문자열' 같은 리터럴을 전달 OUT/IN OUT은 반드시 변수로 전달
DATE/TIMESTAMP 혼용 TO_DATE 없이 문자열을 넘기거나, TIMESTAMP 기대에 DATE를 전달 TO_DATE/TO_TIMESTAMP로 형을 명확히 맞춤
NUMBER/문자 암묵 변환 문자열 숫자, 소수점/지역화(NLS) 이슈 TO_NUMBER + NLS 설정 고려 또는 바인드 타입 수정
레코드/컬렉션 타입 사용자 정의 타입(OBJECT/TABLE) 기대에 일반 값 전달 정의된 타입으로 생성/초기화 후 전달

실전 예시: NULL 때문에 실패하는 호출

-- 잘못된 예(타입 모호)
BEGIN
  pkg_sample.proc_update(p_id => 10, p_memo => NULL);
END;
/

-- 개선 예(타입 명시)
BEGIN
  pkg_sample.proc_update(p_id => 10, p_memo => CAST(NULL AS VARCHAR2));
END;
/

실전 예시: OUT 파라미터에 리터럴 전달

-- 잘못된 예(OUT은 변수 필요)
BEGIN
  pkg_sample.proc_get(p_id => 10, p_result => 'X');
END;
/

-- 개선 예
DECLARE
  v_result VARCHAR2(100);
BEGIN
  pkg_sample.proc_get(p_id => 10, p_result => v_result);
  -- DBMS_OUTPUT.PUT_LINE(v_result);
END;
/

실전 예시: 오버로드 선택을 명시적으로 고정

-- 오버로드가 있는 경우(예시)
-- proc_run(p_id NUMBER)
-- proc_run(p_id VARCHAR2)

-- 숫자처럼 보이는 문자열을 넘기면 모호해질 수 있음
BEGIN
  pkg_sample.proc_run(p_id => TO_NUMBER('10'));
END;
/

BEGIN
  pkg_sample.proc_run(p_id => TO_CHAR(10));
END;
/

복구

복구는 “호출 구문 수정”과 “정의 정합성 복원” 두 갈래로 나뉩니다.
운영 영향도를 최소화하려면 우선 호출 측에서 타입/인자 전달을 명확히 하는 방식이 안전합니다.

1) 호출 구문에 명명 인자 적용(순서 의존 제거)
2) NULL은 CAST(NULL AS 타입)로 명확화
3) 날짜/숫자/타임스탬프는 TO_DATE/TO_NUMBER/TO_TIMESTAMP로 명확화
4) OUT/IN OUT 파라미터는 변수 선언 후 전달
5) 객체/패키지 정의가 다르면: 컴파일 상태, 배포 누락, 시노님 대상부터 정리
-- (예시) 컴파일 상태 확인
SELECT owner, object_name, object_type, status
FROM all_objects
WHERE owner = UPPER('스키마명')
  AND (object_name = UPPER('패키지명') OR object_name = UPPER('프로시저명'))
ORDER BY object_type;

-- (예시) INVALID라면 재컴파일(권한/정책에 맞춰 수행)
-- ALTER PACKAGE 스키마명.패키지명 COMPILE;
-- ALTER PACKAGE 스키마명.패키지명 COMPILE BODY;

재발 방지

PLS-00306은 “인터페이스 변경”이 통제되지 않을 때 반복됩니다.
프로시저 호출 에러를 줄이려면 호출 규약을 표준화하고, 변경 시 검증 루틴을 자동화하는 편이 효과적입니다.

1) 프로시저/함수 시그니처 변경 시: 변경 이력과 영향 범위(호출자 목록) 기록
2) 호출은 기본적으로 명명 인자 사용(순서 변경 내성 확보)
3) 애플리케이션 바인드 변수 타입 고정(문자/숫자/날짜 혼용 방지)
4) 배포 파이프라인에 컴파일 검증 포함(INVALID 객체 차단)
5) 오버로드는 최소화하고, 필요한 경우 호출 예시를 표준 문장으로 제공

오류 분석 흐름도

┌──────────────────────────────────────────────┐
│ 시작: 프로시저 호출 시 PLS-00306 발생          │
└──────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────┐
│ 1) 호출 대상 확정(스키마/패키지/시노님/링크)   │
└──────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────┐
│ 2) 파라미터 정의 조회(all_arguments)           │
│ - position, data_type, in_out 확인             │
└──────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────┐
│ 3) 호출 인자 1:1 매핑                          │
│ - 개수/순서/타입/IN·OUT/디폴트                 │
└──────────────────────────────────────────────┘
          │                         │
          │ 불일치                  │ 일치처럼 보임
          ▼                         ▼
┌──────────────────────────────┐   ┌──────────────────────────────┐
│ 4A) 호출 구문 수정             │   │ 4B) 모호성 점검               │
│ - 명명 인자/CAST/TO_*          │   │ - 오버로드/NULL/NLS/바인드 타입│
└──────────────────────────────┘   └──────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────┐
│ 5) 재실행 및 재점검                             │
│ - 동일 입력으로 재현 여부, 로그/출력 확인        │
└──────────────────────────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────────┐
│ 6) 재발 방지 적용                               │
│ - 변경관리/컴파일 검증/표준 호출 규약            │
└──────────────────────────────────────────────┘

요약: PLS-00306은 “정의와 호출의 불일치”를 의미합니다.
프로시저 호출 에러로 들어오면, 호출 대상 확정 → all_arguments로 정의 조회 → 호출 인자 매핑 → NULL/오버로드/OUT/형변환을 순서대로 보면 대부분 정리됩니다.
본문 흐름대로 점검하면 PLS-00306을 재현 가능한 형태로 좁히고, 안전하게 복구 및 재발 방지까지 연결할 수 있습니다.

반응형