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

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

이 글에서 다루는 내용

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

ORA-06532 Subscript outside of limit 는?

ORA-06532 에러는 PL/SQL에서 컬렉션(Collection) 타입인 VARRAY 또는 중첩 테이블(Nested Table)에 접근할 때, 선언된 최대 크기를 초과하는 인덱스(Subscript)로 요소에 접근하려 할 때 발생합니다. 쉽게 말해, VARRAY를 최대 5개 요소로 선언했는데 6번째 인덱스에 값을 쓰거나 읽으려 할 때 이 에러가 발생합니다. 이 에러는 주로 반복문(LOOP)에서 컬렉션 크기를 잘못 계산하거나, 동적으로 데이터를 추가하는 과정에서 한도를 초과할 때 자주 목격됩니다.


주요 발생 원인

1. VARRAY 선언 크기를 초과한 인덱스 접근

VARRAY는 선언 시 반드시 최대 크기를 지정해야 하며, 이 크기를 초과하는 인덱스로 접근하면 ORA-06532가 즉시 발생합니다. 예를 들어 TYPE my_array IS VARRAY(5) OF VARCHAR2(100)으로 선언한 경우, 절대로 6번 이상의 인덱스에 접근할 수 없습니다. 이는 런타임 시점에서만 감지되기 때문에 컴파일 단계에서는 에러가 나타나지 않아 개발자가 쉽게 놓칠 수 있습니다.

2. EXTEND 없이 요소를 추가하려는 시도

PL/SQL 컬렉션에서 새로운 요소를 추가하려면 반드시 EXTEND 메서드를 먼저 호출하여 공간을 확보해야 합니다. EXTEND 호출 없이 직접 인덱스에 값을 할당하면, 존재하지 않는 위치에 접근하는 것이므로 ORA-06532 또는 ORA-06533 에러가 발생합니다. 특히 FOR 루프 내에서 EXTEND 호출 순서를 잘못 배치하면 이 상황이 빈번하게 발생합니다.

3. 잘못된 루프 상한값(Upper Bound) 설정

반복문에서 컬렉션의 실제 크기보다 큰 값을 루프 상한값으로 설정하면 ORA-06532가 발생합니다. 예를 들어 FOR i IN 1..10 LOOP처럼 하드코딩된 상한값을 사용하다가 실제 컬렉션에 담긴 데이터가 10개 미만이면 문제가 됩니다. 이러한 하드코딩 방식은 데이터 건수가 동적으로 변할 때 매우 위험하며, .COUNT 또는 .LIMIT 속성을 사용해야 합니다.


해결 방법

원인 1 해결: VARRAY 크기 초과 방지

VARRAY의 최대 크기를 충분히 크게 선언하거나, 접근 전에 현재 인덱스가 .LIMIT 이하인지 확인합니다.

DECLARE
  -- VARRAY를 충분히 크게 선언
  TYPE num_array IS VARRAY(10) OF NUMBER;
  v_nums num_array := num_array(1, 2, 3, 4, 5);
  v_index NUMBER := 6;
BEGIN
  -- 접근 전 LIMIT 체크로 ORA-06532 예방
  IF v_index <= v_nums.LIMIT THEN
    v_nums.EXTEND;
    v_nums(v_index) := 100;
    DBMS_OUTPUT.PUT_LINE('값 추가 성공: ' || v_nums(v_index));
  ELSE
    DBMS_OUTPUT.PUT_LINE('인덱스가 VARRAY 한계를 초과합니다: ' || v_index);
  END IF;
END;
/

원인 2 해결: EXTEND를 올바르게 사용하기

요소를 추가하기 전에 반드시 EXTEND를 호출하여 컬렉션 공간을 확보합니다.

DECLARE
  TYPE str_array IS VARRAY(20) OF VARCHAR2(50);
  v_items str_array := str_array(); -- 빈 컬렉션으로 초기화

  -- 추가할 데이터 목록
  TYPE name_list IS TABLE OF VARCHAR2(50);
  v_names name_list := name_list('Alice', 'Bob', 'Charlie', 'Dave', 'Eve');
BEGIN
  FOR i IN 1..v_names.COUNT LOOP
    -- EXTEND 호출 후 값 할당 (올바른 순서)
    v_items.EXTEND;
    v_items(v_items.LAST) := v_names(i);
    DBMS_OUTPUT.PUT_LINE(i || '번째 항목 추가: ' || v_items(v_items.LAST));
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('총 항목 수: ' || v_items.COUNT);
END;
/

원인 3 해결: 루프 상한값을 동적으로 설정하기

하드코딩된 루프 상한값 대신 .COUNT 속성을 사용하여 안전하게 반복합니다.

DECLARE
  TYPE dept_array IS VARRAY(50) OF VARCHAR2(100);
  v_depts dept_array := dept_array();
  v_dept_name VARCHAR2(100);
BEGIN
  -- 데이터베이스에서 부서명을 컬렉션에 담기
  FOR rec IN (SELECT department_name FROM departments WHERE ROWNUM <= 10) LOOP
    v_depts.EXTEND;
    v_depts(v_depts.LAST) := rec.department_name;
  END LOOP;

  -- 하드코딩 대신 .COUNT 사용 (안전한 방법)
  DBMS_OUTPUT.PUT_LINE('== 부서 목록 ==');
  FOR i IN 1..v_depts.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE(i || ': ' || v_depts(i));
  END LOOP;

  -- LIMIT과 COUNT 차이 확인
  DBMS_OUTPUT.PUT_LINE('LIMIT(최대 크기): ' || v_depts.LIMIT);
  DBMS_OUTPUT.PUT_LINE('COUNT(현재 요소 수): ' || v_depts.COUNT);
END;
/

실전 방어 코드 패턴: 예외 처리 추가

DECLARE
  TYPE score_array IS VARRAY(5) OF NUMBER;
  v_scores score_array := score_array(90, 85, 78, 92, 88);
  v_target_idx NUMBER := 7; -- 의도적으로 범위 초과
BEGIN
  BEGIN
    -- 범위 초과 가능성이 있는 접근
    DBMS_OUTPUT.PUT_LINE('점수: ' || v_scores(v_target_idx));
  EXCEPTION
    WHEN SUBSCRIPT_BEYOND_COUNT THEN
      -- ORA-06533: 초기화된 요소 수를 초과한 경우
      DBMS_OUTPUT.PUT_LINE('[경고] ORA-06533: 현재 요소 범위 초과. COUNT=' || v_scores.COUNT);
    WHEN SUBSCRIPT_OUTSIDE_LIMIT THEN
      -- ORA-06532: VARRAY 최대 한도를 초과한 경우
      DBMS_OUTPUT.PUT_LINE('[오류] ORA-06532: VARRAY 최대 한도 초과. LIMIT=' || v_scores.LIMIT);
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('예상치 못한 에러: ' || SQLERRM);
  END;
END;
/

예방 방법

1. 컬렉션 속성(.COUNT, .LIMIT, .LAST)을 항상 활용하라

루프나 조건문에서 컬렉션 인덱스를 다룰 때는 절대로 숫자를 하드코딩하지 말고, 반드시 .COUNT(현재 요소 수), .LIMIT(VARRAY 최대 한도), .LAST(마지막 유효 인덱스) 속성을 활용하세요. 이 습관 하나만으로도 ORA-06532의 대부분을 예방할 수 있습니다. 특히 VARRAY의 경우 IF v_idx BETWEEN 1 AND v_arr.LIMIT THEN 형태의 범위 검증 로직을 표준 코딩 관례로 정착시키는 것이 좋습니다.

2. 예외 처리 블록에 SUBSCRIPT_OUTSIDE_LIMIT을 명시적으로 포함하라

PL/SQL의 미리 정의된 예외(Predefined Exception)인 SUBSCRIPT_OUTSIDE_LIMIT을 EXCEPTION 블록에 명시적으로 선언하면, 에러가 발생해도 프로그램이 비정상 종료되지 않고 적절한 처리를 할 수 있습니다. 이를 통해 운영 환경에서 예상치 못한 데이터 크기 변화에도 안정적으로 대응할 수 있습니다. 코드 리뷰 시 컬렉션을 다루는 모든 PL/SQL 블록에 이 예외 처리가 포함되어 있는지 반드시 점검하세요.


관련 에러

  • ORA-06533 (Subscript beyond count): ORA-06532와 매우 유사한 에러로, VARRAY의 최대 한도(LIMIT)는 초과하지 않았지만 현재 초기화된 요소 수(COUNT)를 초과한 인덱스에 접근할 때 발생합니다. EXTEND 호출을 빠뜨렸을 때 주로 나타납니다.
  • ORA-06531 (Reference to uninitialized collection): 컬렉션 변수 자체를 초기화하지 않고 사용하려 할 때 발생합니다. my_array := array_type()처럼 빈 생성자로라도 반드시 초기화해야 합니다.
  • ORA-06502 (PL/SQL: numeric or value error): 컬렉션에 담기는 데이터의 타입이나 크기가 선언과 맞지 않을 때 발생할 수 있으며, 컬렉션 관련 에러와 함께 나타나는 경우가 있습니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기