ORA-06503: PL/SQL: Function returned without value は、OracleのPL/SQL関数が RETURN を実行しないまま終了した時に発生するエラーです。検索結果やログでは function returned without value と小文字で見ることもあります。関数は戻り値を返すことが契約なので、正常終了するすべての経路で値を返す必要があります。
よくある原因は、IF や CASE の一部の分岐だけ RETURN がない、EXCEPTION で例外を握りつぶして何も返していない、テストデータでは通っていた条件が本番データでは外れて最後まで到達してしまう、というパターンです。
ORA-06503が出たら、まず関数内のすべての終了経路に
RETURN があるか確認します。次に、WHEN OTHERS THEN NULL のように例外を握りつぶしていないか、呼び出し元の ORA-06512 の行番号から実際に落ちた関数を確認します。コンパイルエラーではなく実行時エラーなので、ORA-06550 とは切り分けて考えます。ORA-06503とは
ORA-06503は、関数が戻り値なしで終了したことを示します。プロシージャは戻り値を返さなくても問題ありませんが、関数は宣言した戻り型に合う値を返す必要があります。
| 対象 | 戻り値 | RETURNなしで終了した場合 |
|---|---|---|
| プロシージャ | なし | 正常終了できる |
| 関数 | あり | ORA-06503 になる |
| 関数の一部分岐 | 条件によってあり/なし | RETURNがない経路で ORA-06503 |
| 例外処理内 | 明示的に返す必要あり | 何も返さないと ORA-06503 |
Oracle公式のORA-06503説明でも、関数が値を返さずに終了したことが原因として示されています。そのため、対処は「どの経路でRETURNを通らなかったか」を見つけることです。
RETURN漏れの基本例
もっとも単純なのは、条件に一致した時だけ RETURN し、条件に一致しなかった時に関数の末尾まで到達してしまうパターンです。
CREATE OR REPLACE FUNCTION get_rank_name(p_score NUMBER)
RETURN VARCHAR2
IS
BEGIN
IF p_score >= 90 THEN
RETURN 'A';
ELSIF p_score >= 80 THEN
RETURN 'B';
END IF;
-- p_score が80未満の場合、RETURNされずに終了する
END;
/
SELECT get_rank_name(70) FROM dual;
-- ORA-06503: PL/SQL: Function returned without value
この関数はコンパイルできる場合がありますが、p_score が80未満になると戻り値がありません。ORA-06503は、このように「文法としては成立しているが、実行経路によって戻り値がない」時に表面化します。
基本の直し方
一番安全なのは、関数の最後にデフォルトの RETURN を置くか、すべての分岐で明示的に戻り値を返すことです。
CREATE OR REPLACE FUNCTION get_rank_name(p_score NUMBER)
RETURN VARCHAR2
IS
BEGIN
IF p_score >= 90 THEN
RETURN 'A';
ELSIF p_score >= 80 THEN
RETURN 'B';
ELSE
RETURN 'C';
END IF;
END;
/
業務上「該当なし」を戻したいなら NULL を返す設計もあります。ただし、呼び出し元が NULL を想定していない場合は別の不具合になるため、戻り値の意味を決めてから実装します。
IF分岐で起きるパターン
IF分岐では、条件を追加した時にRETURN漏れが入りやすくなります。特に、初期値では問題なくても、未知のステータスやNULLが入った時に最後まで抜けるケースがあります。
| パターン | 起きる理由 | 修正方針 |
|---|---|---|
IF に ELSE がない |
どの条件にも一致しない経路がある | ELSE RETURN ... を追加する |
| 条件がNULLになる | 比較結果がTRUEにならない | NULL時の戻り値を決める |
| ステータス追加に未対応 | 新しい値が既存分岐に入らない | 未知値の扱いを明示する |
| 途中で例外が起きる | 例外部でRETURNしない | 返すか再送出するか決める |
CREATE OR REPLACE FUNCTION status_label(p_status VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
IF p_status = 'A' THEN
RETURN '有効';
ELSIF p_status = 'I' THEN
RETURN '無効';
ELSIF p_status IS NULL THEN
RETURN '未設定';
ELSE
RETURN '不明';
END IF;
END;
/
CASE文で起きるパターン
CASE文でも、すべての値を網羅できていないとRETURN漏れになります。式としての CASE を使って戻り値を作ると、経路が見えやすくなります。
CREATE OR REPLACE FUNCTION priority_label(p_priority NUMBER)
RETURN VARCHAR2
IS
BEGIN
RETURN CASE p_priority
WHEN 1 THEN '高'
WHEN 2 THEN '中'
WHEN 3 THEN '低'
ELSE '未分類'
END;
END;
/
条件分岐の書き方は OracleのCASE式ガイド も参考になります。関数では「どの条件でも最終的に値が返るか」を優先して読みやすくします。
EXCEPTIONで握りつぶすと起きる
実務で危険なのが、例外を握りつぶして関数を終わらせるパターンです。WHEN OTHERS THEN NULL は一見安全そうに見えますが、関数では戻り値がなくなるためORA-06503につながります。
CREATE OR REPLACE FUNCTION get_customer_name(p_customer_id NUMBER)
RETURN VARCHAR2
IS
l_name customers.customer_name%TYPE;
BEGIN
SELECT customer_name
INTO l_name
FROM customers
WHERE customer_id = p_customer_id;
RETURN l_name;
EXCEPTION
WHEN OTHERS THEN
NULL;
-- ここで終了すると戻り値がない
END;
/
例外時も値を返す設計なら、何を返すかを明示します。エラーとして扱うべきなら、RAISE で呼び出し元へ再送出します。例外処理全体の設計は PL/SQL例外処理ガイド が参考になります。
CREATE OR REPLACE FUNCTION get_customer_name(p_customer_id NUMBER)
RETURN VARCHAR2
IS
l_name customers.customer_name%TYPE;
BEGIN
SELECT customer_name
INTO l_name
FROM customers
WHERE customer_id = p_customer_id;
RETURN l_name;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
WHEN OTHERS THEN
RAISE;
END;
/
ORA-06512の行番号から原因を追う
ORA-06503は、単独ではどの分岐でRETURN漏れになったか分かりにくいことがあります。エラースタックに ORA-06512 が出ている場合は、行番号から関数内の該当箇所を確認します。ソース確認には USER_SOURCE を使います。
ORA-06503: PL/SQL: Function returned without value ORA-06512: at "APP.GET_RANK_NAME", line 10 ORA-06512: at line 1
SELECT line,
text
FROM user_source
WHERE name = 'GET_RANK_NAME'
AND type = 'FUNCTION'
ORDER BY line;
ORA-06512の読み方 を使うと、呼び出し元ではなく、実際に戻り値なしで終了した関数の行を追いやすくなります。
PLW-05005で事前に検知する
ORA-06503は実行時に出るエラーですが、PL/SQLコンパイラの警告を有効にしていると、戻り値なしで終了する可能性がある関数を PLW-05005 として検知できることがあります。本番で初めて落とさないために、開発時やCIでは PLSQL_WARNINGS を有効にしておくと安全です。
ALTER SESSION SET PLSQL_WARNINGS = 'ENABLE:ALL';
CREATE OR REPLACE FUNCTION get_rank_name(p_score NUMBER)
RETURN VARCHAR2
IS
BEGIN
IF p_score >= 90 THEN
RETURN 'A';
END IF;
END;
/
SHOW ERRORS FUNCTION get_rank_name;
-- PLW-05005: subprogram GET_RANK_NAME returns without value
警告をエラー扱いにしたい場合は、環境に合わせて ERROR:ALL や特定番号の警告だけをエラー化します。チームでPL/SQLを管理しているなら、PL/SQLコンパイル時エラーと警告ガイド と合わせて、警告を放置しない運用にすると再発を減らせます。
| 設定 | 意味 | 使いどころ |
|---|---|---|
ENABLE:ALL |
警告を表示する | 開発時、レビュー前 |
ERROR:ALL |
警告をエラーとして扱う | CIや品質ゲート |
DISABLE:ALL |
警告を表示しない | 原則おすすめしない |
PLW-05005 |
戻り値なしで終了する可能性 | ORA-06503の事前検知 |
コンパイルエラーではなく実行時エラー
ORA-06503は、関数の作成時ではなく実行時に出ることが多いエラーです。ただし PLSQL_WARNINGS を有効にしている場合は、SHOW ERRORS や USER_ERRORS に PLW-05005 が出ることがあります。
| エラー | タイミング | 見る場所 | 関連記事 |
|---|---|---|---|
ORA-06503 |
関数実行時 | 実行経路、RETURN、例外処理 | この記事 |
ORA-06512 |
例外スタック表示時 | 行番号、呼び出し順 | ORA-06512 |
ORA-06550 |
PL/SQLコンパイル/実行呼び出し時 | 構文、宣言、コンパイルエラー | ORA-06550 |
PLS-00201 |
コンパイル時 | 未宣言の識別子 | PLS-00201 |
ストアドプロシージャとファンクションの基本的な作り方は、ストアドプロシージャ・ファンクション作成ガイド にまとめています。
SQLから呼び出す関数でも起きる
PL/SQLブロック内だけでなく、SQLから関数を呼び出した場合にもORA-06503は発生します。画面の一覧取得やレポートSQLで関数を呼んでいると、特定の行だけで落ちることがあります。
SELECT employee_id,
get_rank_name(score) AS rank_name
FROM employee_scores;
-- score が想定外の行に当たると ORA-06503 になる
この場合は、どの入力値でRETURN漏れになるかを絞ります。関数単体で代表値、境界値、NULL、想定外値をテストすると原因を見つけやすくなります。
テスト観点
| テスト値 | 確認すること | 例 |
|---|---|---|
| 通常値 | 想定した戻り値になる | 90、'A' |
| 境界値 | 条件境界でRETURN漏れがない | 79、80、89、90 |
| NULL | NULL時の扱いが決まっている | p_status IS NULL |
| 想定外値 | 未知コードでも戻るか、明示的に例外にする | 'X'、-1 |
| 例外発生時 | 返すか再送出するかが明確 | NO_DATA_FOUND、TOO_MANY_ROWS |
「とりあえずNULLを返す」だけで済ませると、呼び出し元で別の不具合になることがあります。業務上の戻り値としてNULLが妥当か、エラーにすべきかを分けて考えます。
修正方針の選び方
| 状況 | おすすめの修正 | 理由 |
|---|---|---|
| 該当なしが正常系 | RETURN NULL または既定値を返す |
呼び出し元が扱える戻り値にする |
| 想定外値はデータ不備 | RAISE_APPLICATION_ERROR で明示する |
不正データを隠さない |
| 例外を上位で処理したい | RAISE で再送出する |
原因のスタックを保てる |
| 分岐が増え続ける | 最後にデフォルトRETURNを置く | 新しい値でも戻り値なしを避ける |
| 戻り値の種類が多い | CASE式やテーブル参照に寄せる | 分岐漏れを減らせる |
CREATE OR REPLACE FUNCTION status_label(p_status VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
CASE p_status
WHEN 'A' THEN RETURN '有効';
WHEN 'I' THEN RETURN '無効';
ELSE
RAISE_APPLICATION_ERROR(-20001, '未知のステータスです: ' || p_status);
END CASE;
END;
/
チェックリスト
| 項目 | OKの状態 |
|---|---|
| 関数の末尾まで到達しても戻り値がある | 最後に RETURN または明示的な例外がある |
| IF/CASEの全分岐が網羅されている | ELSE やデフォルト値がある |
| NULL入力の扱いが決まっている | NULL用の分岐または戻り値がある |
| 例外処理で握りつぶしていない | RETURN するか RAISE する |
| ORA-06512の行番号を確認した | 落ちた関数と行が特定できている |
| 呼び出し元が戻り値を扱える | NULLや既定値の意味が共有されている |
よくある質問
RETURN NULLでもよいですか?
業務上「該当なし」や「未設定」をNULLで表す設計なら問題ありません。ただし、NULLがエラーを隠すだけなら、RAISE や RAISE_APPLICATION_ERROR を使う方が安全です。
プロシージャでもORA-06503になりますか?
ORA-06503は関数が戻り値なしで終了した時のエラーです。プロシージャ自体には戻り値がないため、通常このエラーの対象は関数です。
コンパイルは成功しているのに実行時に落ちます
すべての入力でRETURNが通るとは限らないためです。境界値、NULL、想定外コード、例外発生時の経路を確認してください。
WHEN OTHERS THEN NULL は避けるべきですか?
原則として避けます。関数では戻り値なしの終了につながりやすく、原因も見えにくくなります。返す値を明示するか、例外を再送出します。
まとめ
ORA-06503は、PL/SQL関数が値を返さずに終了した時に発生します。原因は、RETURN 漏れ、IF/CASEの分岐漏れ、NULLや想定外値、例外処理での握りつぶしが中心です。
対処では、すべての終了経路で RETURN する、例外時は返すか再送出する、ORA-06512 の行番号から実際に落ちた関数を追う、という順で確認します。関数は「必ず戻り値を返す」という前提で設計すると、同じエラーを防ぎやすくなります。
参考
ORA-06503 – Oracle Database Error Help
PLW-05005 – Oracle Database Error Help
PL/SQL Subprograms – Oracle Database PL/SQL Language Reference
RETURN Statement – Oracle Database PL/SQL Language Reference

