2026년 08월 28일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-06503 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-06503 PL/SQL: function returned without value 는?
ORA-06503 에러는 PL/SQL 함수(Function)가 실행을 완료했음에도 불구하고 호출자에게 값을 반환하지 않았을 때 발생하는 오류입니다. Oracle에서 함수는 반드시 RETURN 문을 통해 값을 반환해야 하는데, 모든 실행 경로(코드 흐름)에서 RETURN 문이 보장되지 않거나 실행되지 않은 경우 이 에러가 발생합니다. 특히 복잡한 조건 분기(IF-ELSIF-ELSE)나 예외 처리(EXCEPTION) 블록에서 누락된 RETURN 문이 원인이 되는 경우가 많으며, 개발 초기에는 발견하기 어려워 운영 환경에서 갑자기 나타나는 경우도 빈번합니다.
주요 발생 원인
1. 조건 분기에서 모든 경로에 RETURN 문이 존재하지 않는 경우
가장 흔한 원인으로, IF 또는 CASE 문을 사용할 때 일부 분기에만 RETURN 문이 존재하고 나머지 경로에는 누락된 경우입니다. 예를 들어 IF-ELSIF 구문만 사용하고 ELSE 절 없이 함수가 종료되면, 어떤 조건도 만족하지 않을 때 함수는 아무 값도 반환하지 못하게 됩니다. 이는 논리적으로 “반드시 하나의 조건은 참이다”라고 개발자가 가정했지만, 실제 데이터가 그 가정을 벗어날 때 에러로 이어집니다.
2. EXCEPTION 블록에서 RETURN 문 누락
함수 본문에서 예외가 발생했을 때 EXCEPTION 블록이 실행되는데, 이 블록 내에 RETURN 문이 없으면 예외를 처리한 뒤 함수가 값 없이 종료됩니다. 많은 개발자들이 예외 처리 시 RAISE나 로그 처리만 하고 RETURN 문을 빠뜨리는 실수를 범합니다. 예외 처리 후 기본값(NULL 혹은 특정 값)을 반환하도록 명시적으로 작성해야 이 문제를 피할 수 있습니다.
3. LOOP 또는 커서 처리 중 RETURN 문의 조건부 실행
LOOP 내부에서만 RETURN 문이 존재하고, 루프가 한 번도 실행되지 않거나 조건을 만족하지 못해 RETURN이 실행되지 않는 경우입니다. 예를 들어 커서에서 데이터를 읽어 특정 조건의 행이 있을 때만 반환하는 로직의 경우, 해당 데이터가 없으면 루프가 종료되어 함수가 값 없이 끝나버립니다. 루프 종료 후 반드시 디폴트 RETURN 문을 함수 말미에 배치해야 합니다.
해결 방법
원인 1 해결: 모든 분기에 RETURN 추가
잘못된 코드:
CREATE OR REPLACE FUNCTION get_grade(p_score IN NUMBER) RETURN VARCHAR2 IS
BEGIN
IF p_score >= 90 THEN
RETURN 'A';
ELSIF p_score >= 80 THEN
RETURN 'B';
ELSIF p_score >= 70 THEN
RETURN 'C';
-- ELSE 절 없음 → p_score가 70 미만이면 ORA-06503 발생!
END IF;
END;
/
올바른 코드:
CREATE OR REPLACE FUNCTION get_grade(p_score IN NUMBER) RETURN VARCHAR2 IS
BEGIN
IF p_score >= 90 THEN
RETURN 'A';
ELSIF p_score >= 80 THEN
RETURN 'B';
ELSIF p_score >= 70 THEN
RETURN 'C';
ELSE
RETURN 'F'; -- 모든 경우를 커버하는 ELSE 절 추가
END IF;
END;
/
원인 2 해결: EXCEPTION 블록에 RETURN 추가
잘못된 코드:
CREATE OR REPLACE FUNCTION get_employee_name(p_emp_id IN NUMBER) RETURN VARCHAR2 IS
v_name VARCHAR2(100);
BEGIN
SELECT emp_name INTO v_name
FROM employees
WHERE emp_id = p_emp_id;
RETURN v_name;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('직원을 찾을 수 없습니다.');
-- RETURN 문 누락 → ORA-06503 발생!
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('알 수 없는 에러: ' || SQLERRM);
-- RETURN 문 누락 → ORA-06503 발생!
END;
/
올바른 코드:
CREATE OR REPLACE FUNCTION get_employee_name(p_emp_id IN NUMBER) RETURN VARCHAR2 IS
v_name VARCHAR2(100);
BEGIN
SELECT emp_name INTO v_name
FROM employees
WHERE emp_id = p_emp_id;
RETURN v_name;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('직원을 찾을 수 없습니다.');
RETURN NULL; -- 명시적으로 NULL 반환
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('알 수 없는 에러: ' || SQLERRM);
RETURN NULL; -- 명시적으로 NULL 반환 또는 RAISE로 예외 재발생
END;
/
원인 3 해결: LOOP 종료 후 기본 RETURN 추가
잘못된 코드:
CREATE OR REPLACE FUNCTION get_top_salary(p_dept_id IN NUMBER) RETURN NUMBER IS
v_salary NUMBER;
BEGIN
FOR rec IN (SELECT salary FROM employees
WHERE dept_id = p_dept_id
AND salary > 5000
ORDER BY salary DESC) LOOP
RETURN rec.salary; -- 루프 안에서만 RETURN → 조건 만족 행 없으면 ORA-06503!
END LOOP;
-- 함수 끝에 RETURN 없음
END;
/
올바른 코드:
CREATE OR REPLACE FUNCTION get_top_salary(p_dept_id IN NUMBER) RETURN NUMBER IS
v_salary NUMBER;
BEGIN
FOR rec IN (SELECT salary FROM employees
WHERE dept_id = p_dept_id
AND salary > 5000
ORDER BY salary DESC) LOOP
RETURN rec.salary; -- 첫 번째 행 반환
END LOOP;
RETURN 0; -- 조건 만족 행이 없을 경우 기본값 반환
END;
/
실무 디버깅용 진단 쿼리
현재 컴파일된 함수의 소스를 확인하고 RETURN 패턴을 검토하는 쿼리:
-- 특정 함수의 소스코드 확인
SELECT line, text
FROM user_source
WHERE name = 'GET_GRADE'
AND type = 'FUNCTION'
ORDER BY line;
-- RETURN 문이 포함된 라인만 확인
SELECT line, text
FROM user_source
WHERE name = 'GET_GRADE'
AND type = 'FUNCTION'
AND UPPER(text) LIKE '%RETURN%'
ORDER BY line;
-- 스키마 내 모든 함수의 컴파일 에러 확인
SELECT name, type, line, position, text
FROM user_errors
WHERE type = 'FUNCTION'
ORDER BY name, line;
예방 방법
1. 함수 설계 시 “방어적 코딩(Defensive Coding)” 원칙 적용
함수를 작성할 때 마지막 줄에 반드시 기본 RETURN 문을 먼저 작성하는 습관을 들이는 것이 중요합니다. 이렇게 하면 어떤 조건 분기나 예외가 발생하더라도 함수가 항상 값을 반환하는 구조가 보장됩니다. 또한 코드 리뷰 시 모든 IF/CASE 분기와 EXCEPTION 블록에 RETURN 문이 있는지 체크리스트로 확인하는 절차를 팀 규정으로 정착시키세요.
-- 권장 함수 템플릿 (방어적 코딩 패턴)
CREATE OR REPLACE FUNCTION my_function(p_param IN VARCHAR2) RETURN VARCHAR2 IS
v_result VARCHAR2(200) := NULL; -- 기본값 초기화
BEGIN
-- 비즈니스 로직
IF p_param = 'A' THEN
v_result := '결과A';
ELSIF p_param = 'B' THEN
v_result := '결과B';
ELSE
v_result := '알 수 없음'; -- 항상 값 할당
END IF;
RETURN v_result; -- 단일 RETURN 포인트 사용 권장
EXCEPTION
WHEN OTHERS THEN
-- 로그 처리
RETURN NULL; -- 예외 시에도 반드시 RETURN
END;
/
2. PL/SQL 함수 단위 테스트 자동화 도입
함수를 배포하기 전에 경계값(Boundary Value), NULL 입력, 예외 상황 등 다양한 케이스를 커버하는 단위 테스트를 작성하고, CI/CD 파이프라인에 통합하는 것이 좋습니다. utPLSQL과 같은 오픈소스 PL/SQL 테스트 프레임워크를 활용하면 모든 분기를 자동으로 검증할 수 있으며, 배포 전에 ORA-06503 유발 가능성이 있는 경로를 미리 발견할 수 있습니다.
관련 에러
- ORA-06502:
PL/SQL: numeric or value error— 잘못된 데이터 타입으로 RETURN 시 발생할 수 있으며, ORA-06503과 함께 나타나는 경우가 있습니다. - ORA-06511:
PL/SQL: cursor already open— 커서 처리 로직에서 ORA-06503과 동시에 발생할 수 있는 관련 에러입니다. - ORA-04063:
view/procedure has errors— 함수가 컴파일 에러 상태에서 잘못 호출될 때 ORA-06503과 혼동될 수 있습니다. - ORA-06550:
line X, column Y: PLS-XXXX— PL/SQL 컴파일 단계에서 발생하는 에러로, RETURN 누락이 정적으로 감지되면 이 에러가 먼저 나타납니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.