2026년 08월 21일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-04041 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-04041 package does not exist 는?
ORA-04041 에러는 Oracle 데이터베이스에서 참조하거나 호출하려는 패키지(Package)가 현재 스키마 또는 지정된 스키마에 존재하지 않을 때 발생하는 오류입니다. 주로 PL/SQL 코드 내에서 다른 패키지의 프로시저나 함수를 호출할 때, 또는 패키지를 컴파일하는 과정에서 의존 관계에 있는 패키지가 누락되어 있을 경우에 발생합니다. 이 에러는 개발 환경에서 운영 환경으로 마이그레이션하거나, 스키마 간 객체를 이전할 때 특히 자주 목격되며, 빠른 원인 파악과 조치가 필요합니다.
주요 발생 원인
1. 패키지 자체가 생성되지 않았거나 삭제된 경우
가장 흔한 원인으로, 참조하려는 패키지가 해당 스키마에 애초에 생성된 적이 없거나, 다른 작업 중에 실수로 DROP된 경우입니다. 특히 여러 개발자가 동시에 작업하는 환경에서 한 개발자가 패키지를 삭제했을 때 다른 개발자의 코드가 이 에러를 발생시키는 상황이 자주 발생합니다. 운영 환경 배포 시 스크립트 순서가 잘못되어 패키지 스펙(Spec) 없이 바디(Body)만 배포되거나, 아예 누락되는 경우도 이 범주에 포함됩니다.
2. 권한(Privilege) 또는 시노님(Synonym) 문제
패키지가 다른 스키마에 존재하지만 현재 사용자에게 해당 패키지에 대한 EXECUTE 권한이 부여되지 않은 경우, Oracle은 해당 객체를 “존재하지 않는 것”처럼 처리하여 ORA-04041을 반환합니다. 또한 Public Synonym 또는 Private Synonym이 잘못 설정되어 있거나 아예 없는 경우, 올바른 스키마를 명시하지 않고 패키지를 호출할 때 이 에러가 발생할 수 있습니다. 보안 정책상 권한을 최소화하는 환경에서 특히 주의해야 하는 원인입니다.
3. 패키지 스펙(Specification)과 바디(Body)의 불일치 또는 무효화(Invalid) 상태
패키지 스펙은 존재하지만 바디가 없거나, 반대로 바디만 있고 스펙이 없는 경우 ORA-04041과 유사한 컴파일 오류가 발생할 수 있습니다. 또한 패키지가 의존하는 테이블이나 다른 패키지가 변경·삭제되면 해당 패키지가 INVALID 상태로 전환되고, 이 INVALID 패키지를 참조하는 다른 객체를 컴파일할 때 ORA-04041이 연쇄적으로 발생하기도 합니다.
해결 방법
원인 1 해결: 패키지 존재 여부 확인 및 재생성
먼저 해당 스키마에 패키지가 실제로 존재하는지 확인합니다.
-- 현재 사용자 스키마의 패키지 목록 확인
SELECT object_name, object_type, status
FROM user_objects
WHERE object_type IN ('PACKAGE', 'PACKAGE BODY')
ORDER BY object_name;
-- 특정 패키지명으로 검색
SELECT owner, object_name, object_type, status
FROM all_objects
WHERE object_name = 'PKG_EMPLOYEE' -- 찾으려는 패키지명 대문자로 입력
AND object_type IN ('PACKAGE', 'PACKAGE BODY');
-- DBA 권한이 있는 경우 전체 DB에서 검색
SELECT owner, object_name, object_type, status
FROM dba_objects
WHERE object_name = 'PKG_EMPLOYEE'
AND object_type IN ('PACKAGE', 'PACKAGE BODY');
패키지가 존재하지 않는다면 스펙과 바디를 순서대로 생성해야 합니다.
-- 패키지 스펙(Specification) 먼저 생성
CREATE OR REPLACE PACKAGE pkg_employee AS
PROCEDURE get_employee_info(p_emp_id IN NUMBER);
FUNCTION get_salary(p_emp_id IN NUMBER) RETURN NUMBER;
END pkg_employee;
/
-- 패키지 바디(Body) 생성
CREATE OR REPLACE PACKAGE BODY pkg_employee AS
PROCEDURE get_employee_info(p_emp_id IN NUMBER) IS
v_name VARCHAR2(100);
v_dept VARCHAR2(100);
BEGIN
SELECT e.ename, d.dname
INTO v_name, v_dept
FROM emp e
JOIN dept d ON e.deptno = d.deptno
WHERE e.empno = p_emp_id;
DBMS_OUTPUT.PUT_LINE('이름: ' || v_name || ', 부서: ' || v_dept);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('해당 사원을 찾을 수 없습니다.');
END get_employee_info;
FUNCTION get_salary(p_emp_id IN NUMBER) RETURN NUMBER IS
v_sal NUMBER;
BEGIN
SELECT sal INTO v_sal
FROM emp
WHERE empno = p_emp_id;
RETURN v_sal;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 0;
END get_salary;
END pkg_employee;
/
원인 2 해결: 권한 및 시노님 확인 및 부여
-- 특정 사용자가 패키지에 대한 권한을 가지고 있는지 확인
SELECT grantee, owner, table_name, privilege
FROM dba_tab_privs
WHERE table_name = 'PKG_EMPLOYEE'
AND grantee = 'APP_USER'; -- 확인할 사용자명
-- 권한 부여 (DBA 또는 패키지 소유자가 실행)
GRANT EXECUTE ON hr.pkg_employee TO app_user;
-- Public Synonym 확인
SELECT synonym_name, table_owner, table_name
FROM all_synonyms
WHERE synonym_name = 'PKG_EMPLOYEE';
-- Public Synonym 생성 (필요한 경우)
CREATE OR REPLACE PUBLIC SYNONYM pkg_employee
FOR hr.pkg_employee;
-- 특정 사용자를 위한 Private Synonym 생성
CREATE OR REPLACE SYNONYM app_user.pkg_employee
FOR hr.pkg_employee;
원인 3 해결: INVALID 패키지 재컴파일
-- INVALID 상태의 객체 전체 목록 확인
SELECT owner, object_name, object_type, last_ddl_time
FROM dba_objects
WHERE status = 'INVALID'
AND object_type IN ('PACKAGE', 'PACKAGE BODY', 'PROCEDURE', 'FUNCTION')
ORDER BY owner, object_type, object_name;
-- 특정 패키지 수동 재컴파일
ALTER PACKAGE pkg_employee COMPILE;
ALTER PACKAGE pkg_employee COMPILE BODY;
-- 패키지 의존성 확인
SELECT name, type, referenced_owner, referenced_name, referenced_type
FROM user_dependencies
WHERE name = 'PKG_EMPLOYEE';
-- Oracle 제공 유틸리티를 사용한 전체 INVALID 객체 일괄 재컴파일
-- (SYS 또는 DBA 권한 필요)
EXEC UTL_RECOMP.recomp_serial();
-- 또는 병렬 처리 (멀티코어 환경 권장)
EXEC UTL_RECOMP.recomp_parallel(4); -- 4개 스레드 병렬 실행
예방 방법
1. 배포 스크립트에 객체 존재 여부 검증 단계 추가
운영 환경 배포 전 반드시 스크립트 내에서 의존 패키지가 모두 정상적으로 존재하고 VALID 상태인지 자동으로 검증하는 단계를 포함시켜야 합니다. 아래와 같은 검증 스크립트를 배포 파이프라인(CI/CD)에 통합하면 누락 및 INVALID 상태의 패키지를 사전에 탐지할 수 있습니다.
-- 배포 전 검증 스크립트 예시: INVALID 객체가 있으면 오류 발생
DECLARE
v_count NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_count
FROM user_objects
WHERE status = 'INVALID'
AND object_type IN ('PACKAGE', 'PACKAGE BODY');
IF v_count > 0 THEN
RAISE_APPLICATION_ERROR(-20001,
'INVALID 상태의 패키지가 ' || v_count || '개 존재합니다. 배포를 중단합니다.');
END IF;
DBMS_OUTPUT.PUT_LINE('검증 완료: 모든 패키지가 VALID 상태입니다.');
END;
/
2. 패키지 의존성 문서화 및 생성 순서 관리
모든 패키지의 의존 관계를 문서화하고, 배포 스크립트를 항상 의존성 순서에 맞게 정렬하여 관리해야 합니다. 특히 A 패키지가 B 패키지를 참조하는 경우 반드시 B를 먼저 생성해야 하며, 이 순서가 스크립트에 자동으로 반영되도록 Flyway, Liquibase 같은 DB 마이그레이션 도구를 활용하거나, 사내 배포 표준을 수립하는 것이 바람직합니다.
관련 에러
- ORA-04063:
package body has errors— 패키지 바디에 컴파일 오류가 있을 때 발생하며, ORA-04041과 함께 자주 나타납니다. - ORA-06508:
PL/SQL: could not find program unit being called— 런타임 시점에 호출한 패키지나 프로시저를 찾지 못할 때 발생합니다. - ORA-04065:
not executed, altered or dropped package— 패키지가 런타임 중에 변경되거나 삭제된 경우 나타나는 에러입니다. - ORA-00904:
invalid identifier— 패키지 내 잘못된 컬럼명이나 변수명 참조 시 발생하며, INVALID 패키지의 원인이 되기도 합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.