2026년 09월 03일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-06592 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-06592 CASE not found while executing CASE statement 는?
ORA-06592 에러는 Oracle의 CASE 문(CASE statement) 또는 CASE 식(CASE expression)을 실행하는 도중, 어떠한 WHEN 조건도 참(TRUE)이 되지 않고 ELSE 절도 존재하지 않을 때 발생하는 런타임 오류입니다. 즉, CASE 문이 처리해야 할 값이나 조건에 해당하는 분기를 찾지 못했을 때 Oracle 엔진이 던지는 예외입니다. 이 에러는 주로 PL/SQL의 CASE 문(statement) 환경에서 발생하며, SQL의 CASE 식(expression)에서는 NULL을 반환하는 것과 달리 PL/SQL에서는 명시적으로 예외를 발생시킨다는 점이 중요합니다.
주요 발생 원인
1. ELSE 절 없이 모든 WHEN 조건이 불일치하는 경우
PL/SQL의 CASE 문에서 ELSE 절을 생략하고, 실행 시점에 어떤 WHEN 조건도 만족하지 않을 때 ORA-06592가 발생합니다. SQL의 CASE 식과 달리 PL/SQL CASE 문은 묵시적으로 NULL을 반환하지 않으며, 반드시 하나의 분기가 선택되어야 합니다. 예를 들어 WHEN 절에 ‘A’, ‘B’, ‘C’만 정의해 두었는데 실제 데이터에 ‘D’가 입력되면 에러가 발생합니다.
2. 데이터 타입 불일치로 인한 조건 미충족
CASE 문의 비교 대상과 WHEN 절의 값이 데이터 타입이 달라서 묵시적 변환이 실패하거나 예상치 못한 비교 결과가 나오는 경우에도 에러가 발생합니다. 예를 들어 숫자형 컬럼을 문자열 리터럴과 비교하거나, DATE 타입 값을 VARCHAR2와 비교할 때 형변환 오류가 겹쳐 어떤 WHEN 조건도 매칭되지 않는 상황이 생길 수 있습니다. 이러한 경우 개발자는 데이터 타입을 명시적으로 일치시켜야 합니다.
3. NULL 값 처리 누락
비교 대상 값이 NULL인 경우 일반적인 WHEN 절(예: WHEN NULL THEN)은 동작하지 않습니다. Oracle에서 NULL은 어떤 값과도 같지 않으며(NULL = NULL은 FALSE), WHEN NULL은 실제로 비교를 수행하지 못합니다. 따라서 NULL을 처리하려면 반드시 WHEN value IS NULL이 아닌 IS NULL 조건 형태의 SEARCHED CASE나, ELSE 절로 NULL을 명시적으로 처리해야 합니다.
해결 방법
원인 1 해결: ELSE 절 추가
가장 근본적인 해결책은 CASE 문에 항상 ELSE 절을 추가하는 것입니다. ELSE 절이 있으면 어떤 WHEN 조건도 만족하지 않을 때 ELSE 블록이 실행되어 ORA-06592를 방지할 수 있습니다.
-- 문제가 되는 코드
DECLARE
v_grade VARCHAR2(1) := 'D';
v_result VARCHAR2(20);
BEGIN
CASE v_grade
WHEN 'A' THEN v_result := 'Excellent';
WHEN 'B' THEN v_result := 'Good';
WHEN 'C' THEN v_result := 'Average';
-- 'D'에 해당하는 조건 없음 -> ORA-06592 발생
END CASE;
DBMS_OUTPUT.PUT_LINE(v_result);
END;
/
-- 해결된 코드: ELSE 절 추가
DECLARE
v_grade VARCHAR2(1) := 'D';
v_result VARCHAR2(20);
BEGIN
CASE v_grade
WHEN 'A' THEN v_result := 'Excellent';
WHEN 'B' THEN v_result := 'Good';
WHEN 'C' THEN v_result := 'Average';
ELSE v_result := 'Unknown Grade'; -- ELSE로 기본값 처리
END CASE;
DBMS_OUTPUT.PUT_LINE(v_result);
END;
/
원인 2 해결: 데이터 타입 명시적 변환
비교 대상과 WHEN 값의 타입을 명시적으로 맞춰 주면 묵시적 변환 문제를 해결할 수 있습니다.
-- 문제가 되는 코드: 숫자를 문자 리터럴과 비교
DECLARE
v_code NUMBER := 1;
v_result VARCHAR2(20);
BEGIN
CASE v_code
WHEN '1' THEN v_result := 'One'; -- 타입 불일치 가능성
WHEN '2' THEN v_result := 'Two';
ELSE v_result := 'Other';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_result);
END;
/
-- 해결된 코드: 타입을 명시적으로 일치
DECLARE
v_code NUMBER := 1;
v_result VARCHAR2(20);
BEGIN
CASE v_code
WHEN 1 THEN v_result := 'One'; -- 숫자 리터럴 사용
WHEN 2 THEN v_result := 'Two';
ELSE v_result := 'Other';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_result);
END;
/
-- Searched CASE를 사용하여 명시적 형변환 병행
DECLARE
v_code VARCHAR2(10) := '001';
v_result VARCHAR2(20);
BEGIN
CASE
WHEN TO_NUMBER(v_code) = 1 THEN v_result := 'One';
WHEN TO_NUMBER(v_code) = 2 THEN v_result := 'Two';
ELSE v_result := 'Other';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_result);
END;
/
원인 3 해결: NULL 값 명시적 처리
NULL 값을 안전하게 처리하려면 Searched CASE 형태와 IS NULL 조건을 함께 사용해야 합니다.
-- 문제가 되는 코드: NULL 처리 불가
DECLARE
v_value VARCHAR2(10) := NULL;
v_result VARCHAR2(20);
BEGIN
CASE v_value
WHEN NULL THEN v_result := 'Is Null'; -- 이 방식은 동작하지 않음!
WHEN 'A' THEN v_result := 'Letter A';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_result);
END;
/
-- 해결된 코드: Searched CASE + IS NULL 사용
DECLARE
v_value VARCHAR2(10) := NULL;
v_result VARCHAR2(20);
BEGIN
CASE
WHEN v_value IS NULL THEN v_result := 'Is Null'; -- IS NULL로 명시적 처리
WHEN v_value = 'A' THEN v_result := 'Letter A';
ELSE v_result := 'Other Value';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_result);
END;
/
-- NVL을 활용한 방어 코드
DECLARE
v_value VARCHAR2(10) := NULL;
v_result VARCHAR2(20);
BEGIN
CASE NVL(v_value, 'NULL_SUBSTITUTE')
WHEN 'NULL_SUBSTITUTE' THEN v_result := 'Is Null';
WHEN 'A' THEN v_result := 'Letter A';
ELSE v_result := 'Other Value';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_result);
END;
/
EXCEPTION 핸들러를 통한 런타임 보호
이미 배포된 코드에서 즉시 방어가 필요한 경우, CASE_NOT_FOUND 예외를 명시적으로 잡아서 처리할 수 있습니다.
DECLARE
v_status VARCHAR2(10) := 'UNKNOWN';
v_result VARCHAR2(50);
BEGIN
CASE v_status
WHEN 'ACTIVE' THEN v_result := '활성 상태';
WHEN 'INACTIVE' THEN v_result := '비활성 상태';
WHEN 'PENDING' THEN v_result := '대기 상태';
-- ELSE 없이 EXCEPTION으로 처리
END CASE;
DBMS_OUTPUT.PUT_LINE(v_result);
EXCEPTION
WHEN CASE_NOT_FOUND THEN
-- ORA-06592에 대응하는 PL/SQL 사전정의 예외
DBMS_OUTPUT.PUT_LINE('정의되지 않은 상태값: ' || v_status);
-- 필요에 따라 로깅 또는 기본값 처리
v_result := '알 수 없는 상태';
END;
/
예방 방법
1. CASE 문 작성 시 ELSE 절을 코딩 표준으로 강제화
모든 PL/SQL CASE 문에는 반드시 ELSE 절을 포함하도록 개발 가이드라인과 코드 리뷰 체크리스트에 명시해야 합니다. 특히 외부 시스템에서 입력되는 데이터나 코드 테이블(Code Table) 기반으로 분기하는 CASE 문은 데이터가 언제 어떻게 변경될지 예측하기 어렵기 때문에, ELSE 절에 로깅 또는 기본값 처리 로직을 반드시 넣는 것이 좋습니다. 정적 분석 도구(PL/SQL 린터 등)를 CI/CD 파이프라인에 연결하여 ELSE 누락을 자동으로 감지하도록 구성하면 더욱 효과적입니다.
2. 단위 테스트에서 경계값 및 NULL, 예외값 케이스를 반드시 포함
CASE 문이 포함된 PL/SQL 프로시저나 함수를 개발할 때, 정의된 WHEN 절에 해당하는 값뿐만 아니라 정의되지 않은 값(예: 새로운 코드값, NULL, 빈 문자열)에 대한 테스트 케이스를 단위 테스트(utPLSQL, DBMS_ASSERT 등)에 반드시 포함해야 합니다. 이를 통해 운영 환경 배포 전에 ORA-06592 가능성을 사전에 탐지하고, 코드 테이블 변경 시에도 영향 분석을 수행하는 습관을 갖추어야 합니다.
관련 에러
- ORA-06548:
NO_DATA_NEEDED— CASE와 직접 연관은 없으나 PL/SQL 런타임 흐름 제어 관련 예외 - ORA-01403:
NO_DATA_FOUND— SELECT INTO 구문에서 데이터가 없을 때 발생하는 예외로, CASE 문과 함께 사용 시 혼동될 수 있음 - ORA-06502:
VALUE_ERROR— CASE 문에서 반환된 값을 변수에 할당할 때 타입 불일치 또는 크기 초과 시 발생 - PL/SQL 사전정의 예외
CASE_NOT_FOUND: ORA-06592에 대응하는 PL/SQL 내장 예외명으로,EXCEPTION WHEN CASE_NOT_FOUND THEN구문으로 직접 핸들링 가능
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.