Oracle ORA-06530 오류 원인과 해결 방법 완벽 가이드

ORA-06530
2026년 08월 30일 | DBMS Error 가이드

이 글에서 다루는 내용

ORA-06530 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

ORA-06530 Reference to uninitialized composite 는?

ORA-06530 에러는 Oracle PL/SQL 환경에서 초기화되지 않은 복합 타입(Composite Type) — 즉, 오브젝트 타입(Object Type), 컬렉션(Collection), 또는 레코드(Record) 등 — 을 참조하거나 그 멤버에 접근하려 할 때 발생하는 런타임 에러입니다. 쉽게 말해, 변수를 선언만 하고 실제로 인스턴스를 생성하거나 초기화하지 않은 상태에서 해당 변수의 속성(Attribute)이나 메서드(Method)를 호출했을 때 Oracle이 이 에러를 던집니다. 특히 Oracle Object-Oriented 기능을 활용하는 복잡한 PL/SQL 패키지나 타입 계층 구조에서 자주 목격되며, 초보 개발자뿐만 아니라 숙련된 DBA도 실수하기 쉬운 에러 중 하나입니다.


주요 발생 원인

1. 오브젝트 타입 변수를 선언 후 생성자(Constructor) 호출 없이 사용

Oracle에서 사용자 정의 오브젝트 타입(User-Defined Object Type)을 변수로 선언하면, 그 변수는 기본적으로 NULL 상태입니다. 많은 개발자들이 변수를 선언하는 것만으로 인스턴스가 생성된다고 착각하지만, 실제로는 반드시 생성자(TYPE_NAME(...))를 호출하여 오브젝트를 초기화해야 합니다. 초기화 없이 속성에 접근하거나 멤버 메서드를 호출하면 즉시 ORA-06530이 발생합니다.

-- 에러 발생 예시: 초기화 없이 오브젝트 속성에 접근
CREATE OR REPLACE TYPE emp_obj AS OBJECT (
    emp_id   NUMBER,
    emp_name VARCHAR2(100)
);
/

DECLARE
    v_emp emp_obj;  -- 선언만 하고 초기화 안 함
BEGIN
    v_emp.emp_id := 1001;  -- ORA-06530 발생!
    DBMS_OUTPUT.PUT_LINE(v_emp.emp_name);
END;
/

2. 컬렉션(Nested Table, VARRAY) 초기화 없이 요소 접근 또는 삽입

Nested Table이나 VARRAY 타입의 변수 역시 선언만으로는 사용할 수 없습니다. 컬렉션 변수를 사용하기 위해서는 반드시 생성자를 이용해 초기화하거나, EXTEND 메서드를 호출하기 전에 빈 컬렉션이라도 초기화해야 합니다. 초기화하지 않은 상태에서 COUNT, EXTEND, FIRST, LAST 같은 컬렉션 메서드를 호출하거나 인덱스로 요소에 접근하면 ORA-06530 또는 ORA-06531이 발생할 수 있습니다.

-- 에러 발생 예시: 초기화 없이 Nested Table 접근
CREATE OR REPLACE TYPE num_list AS TABLE OF NUMBER;
/

DECLARE
    v_nums num_list;  -- 초기화 없음
BEGIN
    v_nums.EXTEND;    -- ORA-06530 발생!
    v_nums(1) := 100;
END;
/

3. 함수/프로시저에서 OUT 파라미터로 오브젝트를 반환할 때 초기화 누락

프로시저나 함수에서 복합 타입을 OUT 또는 IN OUT 파라미터로 사용하는 경우, 호출부에서 해당 변수를 초기화하지 않고 넘기거나, 프로시저 내부에서 초기화를 잊어버리는 경우에도 이 에러가 발생합니다. 특히 오브젝트 타입을 파라미터로 주고받는 복잡한 비즈니스 로직에서 자주 발생하며, 코드 리뷰 없이는 원인을 찾기 어렵습니다.

-- 에러 발생 예시: OUT 파라미터 초기화 누락
CREATE OR REPLACE PROCEDURE get_emp_info (
    p_emp OUT emp_obj
) IS
BEGIN
    -- p_emp 초기화 없이 속성 설정 시도
    p_emp.emp_id := 9999;  -- ORA-06530 발생!
END;
/

DECLARE
    v_result emp_obj;
BEGIN
    get_emp_info(v_result);
END;
/

해결 방법

원인 1 해결: 오브젝트 타입 생성자 호출로 초기화

오브젝트 타입을 사용하기 전에 반드시 생성자를 호출하여 인스턴스를 생성합니다.

-- 올바른 예시: 생성자를 이용한 초기화
DECLARE
    v_emp emp_obj;
BEGIN
    -- 생성자를 이용하여 오브젝트 초기화
    v_emp := emp_obj(1001, 'Hong Gil-dong');
    
    -- 이제 안전하게 속성에 접근 가능
    DBMS_OUTPUT.PUT_LINE('사원 ID  : ' || v_emp.emp_id);
    DBMS_OUTPUT.PUT_LINE('사원 이름: ' || v_emp.emp_name);
END;
/

-- 또는 NULL 값으로 초기화 후 개별 속성 설정
DECLARE
    v_emp emp_obj;
BEGIN
    v_emp := emp_obj(NULL, NULL);  -- NULL 생성자로 초기화
    v_emp.emp_id   := 1002;
    v_emp.emp_name := 'Kim Chul-su';
    DBMS_OUTPUT.PUT_LINE('사원 ID  : ' || v_emp.emp_id);
    DBMS_OUTPUT.PUT_LINE('사원 이름: ' || v_emp.emp_name);
END;
/

원인 2 해결: 컬렉션 생성자로 초기화 후 사용

-- 올바른 예시: Nested Table 초기화
DECLARE
    v_nums num_list;
BEGIN
    -- 빈 컬렉션으로 초기화
    v_nums := num_list();
    
    -- EXTEND 후 값 할당
    v_nums.EXTEND(3);
    v_nums(1) := 100;
    v_nums(2) := 200;
    v_nums(3) := 300;
    
    -- 컬렉션 출력
    FOR i IN v_nums.FIRST .. v_nums.LAST LOOP
        DBMS_OUTPUT.PUT_LINE('값 [' || i || ']: ' || v_nums(i));
    END LOOP;
END;
/

-- 또는 초기값을 포함하여 바로 초기화
DECLARE
    v_nums num_list;
BEGIN
    v_nums := num_list(10, 20, 30, 40, 50);
    DBMS_OUTPUT.PUT_LINE('요소 개수: ' || v_nums.COUNT);
END;
/

원인 3 해결: 프로시저 내부 또는 호출부에서 초기화

-- 올바른 예시: 프로시저 내부에서 OUT 파라미터 초기화
CREATE OR REPLACE PROCEDURE get_emp_info (
    p_emp_id IN  NUMBER,
    p_emp    OUT emp_obj
) IS
BEGIN
    -- 프로시저 내부에서 생성자로 초기화
    p_emp := emp_obj(NULL, NULL);
    
    -- 이후 속성 설정
    SELECT employee_id, first_name || ' ' || last_name
    INTO   p_emp.emp_id, p_emp.emp_name
    FROM   employees
    WHERE  employee_id = p_emp_id;
    
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        p_emp := emp_obj(p_emp_id, 'NOT FOUND');
END;
/

-- 호출부 예시
DECLARE
    v_result emp_obj;
BEGIN
    get_emp_info(100, v_result);
    DBMS_OUTPUT.PUT_LINE('사원 이름: ' || v_result.emp_name);
END;
/

IS NULL 체크를 통한 방어적 코딩

-- 오브젝트가 초기화되었는지 확인 후 사용
DECLARE
    v_emp emp_obj;
BEGIN
    -- 조건에 따라 초기화
    IF v_emp IS NULL THEN
        v_emp := emp_obj(0, 'DEFAULT');
        DBMS_OUTPUT.PUT_LINE('오브젝트를 기본값으로 초기화했습니다.');
    END IF;
    
    DBMS_OUTPUT.PUT_LINE('사원 ID: ' || v_emp.emp_id);
END;
/

예방 방법

1. 선언과 동시에 초기화하는 습관 정착 (Declaration-Time Initialization)

복합 타입 변수를 선언할 때 반드시 그 자리에서 초기화하는 코딩 컨벤션을 팀 전체에 정착시켜야 합니다. DECLARE 섹션에서 변수 선언과 동시에 생성자를 호출하면, 초기화 누락으로 인한 런타임 에러를 원천적으로 차단할 수 있습니다. 코드 리뷰 체크리스트에 “모든 복합 타입 변수는 선언 시 초기화 여부 확인” 항목을 반드시 추가하세요.

-- Best Practice: 선언과 동시에 초기화
DECLARE
    -- 오브젝트 타입: 선언과 동시에 초기화
    v_emp  emp_obj  := emp_obj(NULL, NULL);
    -- 컬렉션 타입: 선언과 동시에 빈 컬렉션으로 초기화
    v_nums num_list := num_list();
BEGIN
    v_emp.emp_id   := 2001;
    v_emp.emp_name := 'Lee Young-hee';
    v_nums.EXTEND;
    v_nums(1) := 999;
    DBMS_OUTPUT.PUT_LINE(v_emp.emp_name || ' / ' || v_nums(1));
END;
/

2. 예외 처리 블록과 방어적 NULL 체크 병행

복잡한 비즈니스 로직에서는 오브젝트 타입 변수가 여러 경로로 할당될 수 있으므로, 중요한 접근 포인트마다 IS NULL 체크와 함께 EXCEPTION 블록에서 ORA-06530을 명시적으로 처리하는 방어 코드를 작성하세요. 이렇게 하면 에러 발생 시 원인을 즉시 파악하고, 사용자에게 친절한 오류 메시지를 전달할 수 있습니다.

-- Best Practice: NULL 체크 + 예외 처리
DECLARE
    v_emp emp_obj;
    
    PROCEDURE safe_set_emp (
        p_obj  IN OUT emp_obj,
        p_id   IN     NUMBER,
        p_name IN     VARCHAR2
    ) IS
    BEGIN
        IF p_obj IS NULL THEN
            p_obj := emp_obj(NULL, NULL);
        END IF;
        p_obj.emp_id   := p_id;
        p_obj.emp_name := p_name;
    END;
    
BEGIN
    safe_set_emp(v_emp, 3001, 'Park Min-jun');
    DBMS_OUTPUT.PUT_LINE('처리 완료: ' || v_emp.emp_name);
EXCEPTION
    WHEN OTHERS THEN
        IF SQLCODE = -6530 THEN
            DBMS_OUTPUT.PUT_LINE('복합 타입 초기화 오류 발생. 담당자에게 문의하세요.');
        ELSE
            RAISE;
        END IF;
END;
/

관련 에러

  • ORA-06531: Reference to uninitialized collection — ORA-06530과 매우 유사하며, 컬렉션 타입(Nested Table, VARRAY)이 초기화되지 않은 상태에서 컬렉션 메서드(EXTEND, COUNT 등)를 호출할 때 발생합니다. ORA-06530이 오브젝트 타입 전반에 적용된다면, ORA-06531은 컬렉션에 특화된 에러입니다.
  • ORA-06532: Subscript outside of limit — VARRAY의 최대 크기를 초과하는 인덱스로 접근할 때 발생합니다.
  • ORA-06533: Subscript beyond count — 컬렉션의 현재 요소 개수를 초과하는 인덱스로 접근할 때 발생합니다.
  • ORA-21700: Object does not exist or is marked for delete — 오브젝트 타입 인스턴스가 삭제된 상태에서 접근할 때 발생하는 관련 에러입니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기