본문 바로가기
IT

ORA-06550 PL/SQL compilation error — 컴파일 오류 원인·해결·예방 완전 정리

by 샤나엘 2026. 5. 19.
반응형

ORA-06550 PL/SQL compilation error — 컴파일 오류 원인·해결·예방 완전 정리

PL/SQL 익명 블록이나 동적 SQL을 던졌을 때 ORA-06550: line X, column Y: PLS-NNNNN: ... 형태로 떨어지는 에러는 사실상 모든 PL/SQL 개발자가 한 번쯤 본다. ORA-06550은 항상 PLS-xxxxx 컴파일러 메시지와 함께 묶여 나타나는 wrapper로, PL/SQL 코드가 컴파일 단계에서 실패했음을 알려 주는 신호다.

 

본 글은 ORA-06550의 정확한 의미와 ORA-06512·ORA-04063과의 구분, 자주 함께 나타나는 7가지 PLS 컴파일 에러, line·column 좌표를 활용한 진단, 동적 SQL 안전화와 빌드 단계의 정적 분석까지 정리한다.

ORA-06550

 

이 글의 구성

 

01에러 메시지와 ORA-06550의 의미
02발생 시점 — 어디서 컴파일이 일어나는가
03자주 함께 나타나는 PLS 코드 7가지
04line·column 좌표와 진단 절차
05예방 전략과 동적 SQL 안전화
06ORA-06512·ORA-04063과의 차이
Q&A자주 묻는 질문 5가지

01 에러 메시지와 ORA-06550의 의미

항목 내용
에러 코드 ORA-06550
메시지 형식 line X, column Y: PLS-NNNNN: <세부 메시지>
시점 PL/SQL 컴파일 단계(런타임 아님)
실제 원인 함께 표시된 PLS-NNNNN 코드
EXCEPTION 처리 불가 — 컴파일이 실패하므로 핸들러 자체가 동작하지 않음
발생 단위 익명 블록 · EXECUTE IMMEDIATE · DBMS_SQL · CREATE OR REPLACE

전형적인 출력 예시

ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'PROC'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

진단의 출발점은 두 번째 줄의 PLS-NNNNN 코드다. ORA-06550은 "어디서 실패했는가"의 좌표만 알려 주고, 진짜 원인은 PLS 코드에 담겨 있다.

핵심 관찰 — EXCEPTION 블록으로 잡을 수 없다

ORA-06550은 코드가 실행되기 전, 컴파일 단계에서 실패하므로 PL/SQL의 EXCEPTION 핸들러로는 잡히지 않는다. 동적 SQL을 EXECUTE IMMEDIATE로 던졌을 때도 그 안에서 발생한 컴파일 에러는 호출 측 외부에서만 잡을 수 있다. ORA-06512(런타임 백트레이스)와의 결정적 차이가 여기에 있다.


02 발생 시점 — 어디서 컴파일이 일어나는가

PL/SQL 엔진은 다음 다섯 가지 경로에서 코드를 컴파일한다. ORA-06550은 이 다섯 시점 어디서든 발생할 수 있다.

  • 익명 블록 실행 — SQL*Plus·SQL Developer에서 BEGIN ... END;를 던질 때
  • EXECUTE IMMEDIATE — 동적으로 만든 PL/SQL 또는 DDL 문자열을 실행할 때
  • DBMS_SQL.PARSE — 동적 SQL 패키지를 통한 파싱
  • CREATE OR REPLACE — 저장 객체(프로시저·함수·패키지·트리거) DDL
  • 클라이언트 호출 — JDBC·ODP.NET·python-oracledb 등이 PL/SQL 블록을 전송할 때

저장 객체 DDL의 경우 컴파일이 실패하면 객체는 데이터 사전에 INVALID 상태로 남는다. 이때 누군가 이 객체를 호출하면 ORA-04063이 발생하므로, ORA-06550이 처음 떨어진 시점에 바로 잡지 못하면 운영 트래픽에서 ORA-04063으로 재발견된다. 둘은 같은 컴파일 실패의 두 얼굴이다.


03 자주 함께 나타나는 PLS 코드 7가지

코드 의미 흔한 원인
PLS-00103 Encountered the symbol ... 세미콜론 누락, BEGIN/END 짝 불일치
PLS-00201 identifier must be declared 객체 미존재, 권한 없음, 오타
PLS-00302 component must be declared 패키지 멤버·컬럼 이름 잘못
PLS-00306 wrong number or types of arguments 함수·프로시저 시그니처 불일치
PLS-00357 table, view or sequence reference not allowed in this context DML이 허용되지 않는 위치
PLS-00428 INTO clause is expected in this SELECT PL/SQL의 SELECT가 INTO 없이 작성
PLS-00049 bad bind variable 바인드 변수 이름 잘못

PLS-00103·00201·00306이 가장 빈도가 높다. 좌표(line·column)만 알면 어느 토큰에서 컴파일러가 멈춘 것인지 즉시 식별할 수 있고, 이 세 가지를 능숙하게 다루는 것만으로도 일상적 컴파일 오류의 80%는 자력으로 해결된다.


04 line·column 좌표와 진단 절차

SQL*Plus에서 직전 컴파일 객체의 에러 확인

-- 직전 컴파일된 객체의 에러 표시
SHOW ERRORS

-- 객체 지정해서 확인
SHOW ERRORS PROCEDURE my_proc
SHOW ERRORS PACKAGE BODY my_pkg

USER_ERRORS 뷰 — 저장 객체 컴파일 잔여 오류

SELECT name, type, line, position, text
FROM   user_errors
WHERE  name = 'MY_PKG'
   AND  type = 'PACKAGE BODY'
ORDER BY sequence;

저장 객체의 컴파일 시점 ORA-06550은 결과적으로 USER_ERRORS에 PLS 메시지로 남는다. 이 뷰를 CI 파이프라인에서 0건이 될 때까지 검증한 뒤에야 배포를 통과시키는 게이트로 쓰는 것이 표준이다.

EXECUTE IMMEDIATE 디버깅 — 문자열을 정적으로 검증

동적 PL/SQL의 컴파일 오류는 줄 번호가 동적 문자열 내부 기준이라 추적이 어렵다. 가장 빠른 방법은 동적으로 생성된 SQL 문자열을 로그로 그대로 받아 SQL Developer에 붙여 정적 컴파일로 검증하는 것이다.

DECLARE
  v_sql VARCHAR2(4000);
BEGIN
  v_sql := 'BEGIN pkg.do_it(:1); END;';
  DBMS_OUTPUT.PUT_LINE(v_sql);    -- 동적 문자열 로깅
  EXECUTE IMMEDIATE v_sql USING 100;
END;
/

05 예방 전략과 동적 SQL 안전화

영역 권장 조치
작성 단계 SQL Developer·SQLcl의 실시간 syntax check 활용
동적 SQL DBMS_ASSERT로 식별자·값 검증, 바인드 변수 강제(SQL Injection 동시 차단)
빌드 게이트 CI 파이프라인에서 USER_ERRORS 0건 검증 후에만 다음 단계 진행
정적 분석 PL/Scope·SonarQube PL/SQL 룰로 시그니처·미사용 변수·deprecated 호출 점검
단위 테스트 utPLSQL로 정상·예외·경계값 시나리오 자동화
코드 리뷰 패키지 spec 변경 시 dependent body 재컴파일 동반 확인

DBMS_ASSERT로 동적 SQL 안전화

DECLARE
  v_tab  VARCHAR2(30) := 'EMP';
  v_sql  VARCHAR2(4000);
  v_cnt  NUMBER;
BEGIN
  -- 식별자 검증으로 컴파일 실패와 인젝션을 동시에 막는다
  v_sql := 'SELECT COUNT(*) FROM ' ||
           SYS.DBMS_ASSERT.SIMPLE_SQL_NAME(v_tab);
  EXECUTE IMMEDIATE v_sql INTO v_cnt;
END;
/

값은 무조건 바인드 변수(USING)로, 식별자는 DBMS_ASSERT로 검증하는 두 가지 룰이 동적 SQL의 표준이다. 이 두 가지만 지켜도 ORA-06550 빈도와 보안 사고를 동시에 줄일 수 있다.

CI 게이트가 가장 효과적인 안전망

개발자가 로컬에서 컴파일 확인을 빠뜨려도, 빌드 단계에서 USER_ERRORS·DBA_ERRORS를 조회해 0건이 아니면 빌드 실패로 처리하는 룰을 두면 ORA-06550이 운영으로 흘러가지 않는다. 패키지 spec 변경 후 body 재컴파일까지 자동화하면 ORA-04063과의 결합 장애도 같이 막을 수 있다.


06 ORA-06512·ORA-04063과의 차이

에러 코드 시점 의미와 차이
ORA-06550 컴파일 지금 보낸 코드가 컴파일 실패(PLS-NNNNN 동반)
ORA-06512 런타임 이미 컴파일된 코드가 실행 중 예외(위치 표시)
ORA-04063 런타임 호출된 저장 객체가 INVALID 상태
ORA-04088 런타임 트리거 실행 중 예외 wrapper
ORA-06502 런타임 값·자료형 변환 오류(컴파일은 통과)

ORA-06550은 PLS-NNNNN과 함께 컴파일 단계에서 떨어지고, 저장 객체에서 같은 컴파일 실패가 일어났다면 데이터 사전에 INVALID 상태로 남아 이후 호출 시 ORA-04063으로 표면화된다. ORA-06512는 컴파일을 통과한 코드의 실행 중 예외 위치를, ORA-04088은 그것이 트리거 컨텍스트에서 발생했음을 알려 준다. 어느 코드를 만났는지에 따라 진단 시작점이 USER_ERRORS인지 USER_SOURCE인지 자연스럽게 갈린다.


07 자주 묻는 질문

Q1. ORA-06550을 EXCEPTION WHEN OTHERS로 잡을 수 있나요?

없다. 컴파일 단계에서 실패하면 PL/SQL 엔진은 코드 자체를 실행 가능 상태로 만들지 못하므로 EXCEPTION 블록이 동작할 기회가 없다. EXECUTE IMMEDIATE로 동적 PL/SQL을 실행한 호출자 측에서 일반 OTHERS로 잡을 수 있지만, 정적 PL/SQL 블록은 그 위 호출자나 클라이언트 단에서만 잡힌다.

Q2. PLS-00201이 떨어졌는데 SQL*Plus에서는 같은 테이블이 보입니다.

PL/SQL 컴파일은 role 권한을 인정하지 않는다. 권한이 role을 통해 부여됐다면 SELECT는 되지만 PL/SQL 내부 참조에서는 PLS-00201로 떨어진다. 해결은 직접 GRANT 또는 시노님 생성이다. 시노님 경로 자체가 끊어진 경우도 같은 증상을 보인다.

Q3. EXECUTE IMMEDIATE에서 ORA-06550의 라인 번호가 이상해요.

동적 SQL의 line 좌표는 그 문자열 내부 기준이다. 외부 PL/SQL 파일의 라인이 아니다. 디버깅 시 동적 문자열을 DBMS_OUTPUT으로 그대로 찍어 SQL Developer에 붙여 넣으면 라인 좌표가 일치한다.

Q4. PLS-00306 시그니처 불일치는 어떻게 빨리 잡나요?

USER_ARGUMENTS·ALL_ARGUMENTS 뷰에서 해당 패키지·프로시저의 파라미터 시퀀스를 확인한다. named notation(`p_name => value`)으로 호출하면 컴파일 시점에 실수를 빠르게 잡을 수 있고, 의도하지 않은 오버로드 호출도 방지된다.

Q5. 저장 객체를 CREATE OR REPLACE했더니 SUCCESS인데 호출 시 ORA-04063이 떨어집니다.

CREATE OR REPLACE는 컴파일 에러가 있어도 "Warning: ... created with compilation errors" 정도로 통과시키고 INVALID 객체를 만든다. SHOW ERRORS 또는 USER_ERRORS에 PLS-NNNNN이 남아 있고, 누군가 그 객체를 호출하는 순간 ORA-04063이 떨어진다. 배포 직후 반드시 USER_ERRORS 0건 검증이 필요한 이유다.


마무리

ORA-06550은 PL/SQL 학습 곡선의 가장 앞쪽에 놓인 에러다. 막상 처음 보면 막막하지만, 함께 출력되는 PLS-NNNNN 코드와 line·column 좌표만 읽을 줄 알면 대부분 5분 안에 해결된다.

 

진단의 정공법은 (1) PLS 코드로 원인 유형 식별, (2) 좌표로 위치 확인, (3) SHOW ERRORS / USER_ERRORS로 보강, 세 단계다.

 

운영 안정성 측면에서는 (1) 모든 동적 SQL에서 바인드 변수와 DBMS_ASSERT 적용, (2) CI 빌드 단계에 USER_ERRORS 0건 게이트, (3) 패키지 spec 변경 시 dependent 객체 일괄 재컴파일 자동화, (4) 단위 테스트로 호출 경로 커버, 네 가지가 ORA-06550·ORA-04063·ORA-06512 묶음을 한 번에 줄여 준다. 컴파일 실패를 운영 트래픽으로 흘려보내지 않는 것이 PL/SQL 운영의 첫 번째 원칙이다.

ORA-06550 트러블슈팅 체크리스트

 

01동반 PLS-NNNNN 코드로 컴파일 오류 유형 식별(00103·00201·00306 빈도 높음).
02line·column 좌표로 정확한 위치 확보 후 토큰 단위 점검.
03SQL*Plus SHOW ERRORS 또는 USER_ERRORS 뷰로 잔여 PLS 메시지 일괄 확인.
04PLS-00201은 role이 아닌 직접 GRANT 또는 시노님 경로 점검.
05동적 SQL은 EXECUTE IMMEDIATE + USING 바인드 변수와 DBMS_ASSERT 식별자 검증.
06CI 빌드 단계에서 USER_ERRORS 0건이 아니면 빌드 실패 처리.
07패키지 spec 변경 후 body까지 자동 재컴파일로 ORA-04063 결합 차단.

본 글은 Oracle Database PL/SQL 컴파일 오류 ORA-06550의 일반적 원인과 해결 방법을 정리한 자료다. 운영 환경 적용 전 테스트 환경에서 충분히 검증한다.

 

#ORA06550 #PLSQLcompilationError #오라클에러 #PLS00103 #PLS00201 #PLS00306 #익명블록 #EXECUTE_IMMEDIATE #DBMS_SQL #DBMS_ASSERT #바인드변수 #USER_ERRORS #SHOW_ERRORS #PLScope #utPLSQL

반응형

댓글