【完全ガイド】ORA-06502: PL/SQL numeric or value error の原因と解決方法|4種類のサブタイプ・NOT NULL・例外処理 徹底解説
- 作成日 2026.07.31
- Oracle Database その他
PL/SQL 開発者が日常的に遭遇する値エラー:
DECLARE
v_number NUMBER(2);
BEGIN
v_number := 'abc'; -- 文字列 → 数値
END;
/
-- ORA-06502: PL/SQL: numeric or value error: character to number conversion error
-- ORA-06512: at line 4
「値エラー」という広い意味のメッセージ。実は4種類のサブタイプがあり、それぞれ原因が異なります:
character to number conversion error← 文字列→数値失敗character string buffer too small← VARCHAR2 長さ超過null value not allowed← NOT NULL に NULL 代入number precision too large← 数値桁あふれ
さらに、SQL 版の ORA-01722(invalid number)とは違い、PL/SQL 特有の広範な値エラーをカバー:
- 変数への非数値代入
- VARCHAR2(3) に 4 文字代入
- NUMBER(2) に 100代入
- NOT NULL 変数に NULL代入
- 配列インデックス の NULL
- PL/SQL コレクションの型不一致
- EXECUTE IMMEDIATE のバインド不整合
- JDBC / oracledb 経由のパラメータ渡し
- CHAR の連結によるバッファ超過
- REF CURSOR の型不一致
多くの日本語記事が「型が違う」で終わりますが、実務では:
- ORA-06512 で示されるスタックトレースの読み方
VALUE_ERRORvsINVALID_NUMBERの例外区別SUBSTRB/SUBSTRCの使い分け(文字長 vs バイト長)PLS_INTEGER/SIMPLE_INTEGERの落とし穴- Rails / Java / Python からのパラメータ渡し時のトラブル
DBMS_OUTPUTでのデバッグ- 本番でしか出ないタイプの ORA-06502
さらに、Oracle E-Business Suite など大規模システムでは、ORA-06502 の発生位置特定が最重要スキル:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "APPS.FND_NUMBER", line 20
ORA-06512: at "APPS.MY_PKG.PROCESS_ORDER", line 145
ORA-06512: at line 1
スタックトレースから原因パッケージ・行番号を特定するスキルは、PL/SQL 開発者の必須スキルです。
本記事では、ORA-06502: PL/SQL: numeric or value error の完全な原因と解決方法を、リファレンスとして実用的に整理します。4種類のサブタイプ、ORA-01722 との関係、10大発生パターン、ORA-06512 スタックトレース解読、5つの解決策、例外処理、Rails/Java/Python 対応、実践シナリオ、FAQまで完全網羅。この1本で ORA-06502 を根本から解決できるようになります。
- 1. 結論:4種類のサブタイプを理解
- 2. まず理解する:ORA-06502 の本質
- 3. サブタイプ①: character to number conversion error
- 4. サブタイプ②: character string buffer too small
- 5. サブタイプ③: null value not allowed
- 6. サブタイプ④: number precision too large
- 7. 【原因⑤】配列インデックスの NULL
- 8. 【原因⑥】EXECUTE IMMEDIATE のバインド不整合
- 9. 【原因⑦】REF CURSOR の型不一致
- 10. 【原因⑧】SQL からの戻り値型ミスマッチ
- 11. 【原因⑨】PLS_INTEGER の桁あふれ
- 12. 【原因⑩】JDBC / oracledb からのパラメータ渡し
- 13. ORA-06512 スタックトレースの読み方
- 14. 例外処理の完全リファレンス
- 15. 5つの解決策 完全リファレンス
- 16. Rails / Java / Python 対応
- 17. 実践シナリオ
- 18. トラブルシューティング
- 19. よくある質問(FAQ)
- 19.1. Q1. ORA-06502 と ORA-01722 の違い
- 19.2. Q2. VALUE_ERROR と INVALID_NUMBER
- 19.3. Q3. ORA-06512 は?
- 19.4. Q4. サブタイプの見分け方
- 19.5. Q5. VARCHAR2(3 CHAR) vs VARCHAR2(3 BYTE)
- 19.6. Q6. PLS_INTEGER の桁あふれ
- 19.7. Q7. NOT NULL 変数の対処
- 19.8. Q8. Rails での対応
- 19.9. Q9. スタックトレースの読み方
- 19.10. Q10. パフォーマンスへの影響
- 19.11. Q11. Autonomous DB での挙動
- 19.12. Q12. ORA-06502 と DBMS_LOB
- 20. 参考リンク
- 21. まとめ
結論:4種類のサブタイプを理解
時間がない方向けに、最速の対処を先に示します。
4種類のサブタイプ
| サブタイプ | 意味 | 例 |
|---|---|---|
| character to number conversion error | 文字列→数値失敗 | n := 'abc' |
| character string buffer too small | VARCHAR2 長さ超過 | v3 := 'abcde' (v3 は VARCHAR2(3)) |
| null value not allowed | NOT NULL に NULL | n1 := n2(n2 が NULL) |
| number precision too large | 数値桁あふれ | n2 := 100(n2 は NUMBER(2)) |
エラーメッセージの読み方
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "SCHEMA.PROCEDURE", line 20 ← 発生位置
ORA-06512: at "SCHEMA.OUTER_PROC", line 145 ← 呼び出し元
ORA-06512: at line 1 ← 実行位置
ORA-06512 のスタックトレースから発生位置を特定。
ORA-06502 vs ORA-01722
| 項目 | ORA-06502 | ORA-01722 |
|---|---|---|
| レベル | PL/SQL | SQL |
| 範囲 | 広範な値エラー | 数値変換のみ |
| 例外名 | VALUE_ERROR | INVALID_NUMBER |
| スタックトレース | ORA-06512 併発 | なし |
5つの解決策
| # | 手法 | 使う場面 |
|---|---|---|
| ① | 型・サイズ調整 | 通常の対処 |
| ② | EXCEPTION 処理 | 業務継続 |
| ③ | 事前バリデーション | 予防 |
| ④ | PLS_INTEGER 活用 | 高速化 |
| ⑤ | SUBSTR で切り詰め | 文字列超過 |
詳細は以下で解説します。
まず理解する:ORA-06502 の本質
PL/SQL の VALUE_ERROR
PL/SQL では広範な値エラーが VALUE_ERROR で捕捉される:
DECLARE
v_num NUMBER(2);
BEGIN
v_num := 100; -- 桁あふれ
EXCEPTION
WHEN VALUE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('値エラー');
END;
/
エラーメッセージのフルセット
ORA-06502: PL/SQL: numeric or value error{: <detail>}
{} 内が省略される場合もあれば、詳細が表示される場合もある。
ORA-06512 との併発
必ず ORA-06512(スタックトレース)と一緒に出る:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "SCOTT.MY_PROC", line 24
ORA-06512 = 発生位置、ORA-06502 = エラー内容。
サブタイプ①: character to number conversion error
症状
DECLARE
v_num NUMBER;
BEGIN
v_num := 'abc'; -- 明示的な非数値
END;
/
-- ORA-06502: character to number conversion error
変数への代入
DECLARE
v_num NUMBER;
v_str VARCHAR2(10) := 'abc';
BEGIN
v_num := v_str; -- 暗黙変換で失敗
END;
/
-- ORA-06502
EXECUTE IMMEDIATE のバインド
DECLARE
v_num NUMBER;
BEGIN
EXECUTE IMMEDIATE
'SELECT amount FROM orders WHERE id = :1'
INTO v_num USING 'abc';
END;
/
-- ORA-06502('abc' が id と型不一致)
解決
A. 明示的な TO_NUMBER + 例外処理:
DECLARE
v_num NUMBER;
BEGIN
BEGIN
v_num := TO_NUMBER('abc');
EXCEPTION
WHEN VALUE_ERROR OR INVALID_NUMBER THEN
v_num := NULL;
END;
END;
/
B. 12.2+ の DEFAULT ON CONVERSION ERROR:
v_num := TO_NUMBER('abc' DEFAULT 0 ON CONVERSION ERROR);
ORA-01722 の詳細は ORA-01722: invalid number の記事も参照してください。
サブタイプ②: character string buffer too small
症状
DECLARE
v_str VARCHAR2(3);
BEGIN
v_str := 'abcde'; -- 3文字を超える
END;
/
-- ORA-06502: character string buffer too small
CHAR の落とし穴
DECLARE
v_char CHAR(5) := 'A'; -- 実際は 'A '(4スペース)
BEGIN
v_char := v_char || 'B'; -- 'A B' = 6文字
END;
/
-- ORA-06502
CHAR は右パディング、連結すると超過。VARCHAR2 推奨。
VARCHAR2 vs CHAR は文字列型比較の記事も参考になります。
解決
A. サイズ拡大:
v_str VARCHAR2(100);
B. SUBSTR で切り詰め:
v_str := SUBSTR('abcde', 1, 3); -- 'abc'
C. LENGTH で事前チェック:
IF LENGTH(source_str) <= 3 THEN
v_str := source_str;
ELSE
DBMS_OUTPUT.PUT_LINE('長すぎる');
END IF;
バイト長 vs 文字長
DECLARE
v_str VARCHAR2(3 CHAR); -- 3文字(マルチバイトOK)
v_str2 VARCHAR2(3 BYTE); -- 3バイト(日本語 1文字で消費)
BEGIN
v_str := 'あいう'; -- 3文字 = OK
v_str2 := 'あ'; -- 3バイト = OK(UTF-8 は 3バイト)
v_str2 := 'あい'; -- 6バイト = ORA-06502
END;
/
マルチバイトでは VARCHAR2(n CHAR) 推奨。
サブタイプ③: null value not allowed
症状
DECLARE
n1 NUMBER NOT NULL := 1; -- NOT NULL
n2 NUMBER; -- NULL 可
BEGIN
n1 := n2; -- NULL を NOT NULL に
END;
/
-- ORA-06502: null value not allowed
解決
A. NULL チェック:
IF n2 IS NOT NULL THEN
n1 := n2;
END IF;
B. NVL で代替値:
n1 := NVL(n2, 0);
C. NOT NULL 制約を外す(設計見直し):
n1 NUMBER := 1; -- NOT NULL 削除
サブタイプ④: number precision too large
症状
DECLARE
v_num NUMBER(2); -- 最大2桁
BEGIN
v_num := 100; -- 3桁 → 超過
END;
/
-- ORA-06502: number precision too large
-- NUMBER(3, 1) = 全3桁、小数1桁 = 最大 99.9
DECLARE
v_num NUMBER(3, 1);
BEGIN
v_num := 100.5; -- 超過
END;
/
解決
A. 精度を上げる:
v_num NUMBER(5, 2);
B. NUMBER(無制約):
v_num NUMBER; -- 精度指定なし
C. TRUNC / ROUND:
v_num := ROUND(source_num, 1);
NUMBER の詳細は Oracle NUMBER型 vs INTEGER の違いの記事も参照してください。
【原因⑤】配列インデックスの NULL
症状
DECLARE
TYPE t_arr IS TABLE OF VARCHAR2(50) INDEX BY PLS_INTEGER;
v_arr t_arr;
v_key PLS_INTEGER;
BEGIN
v_arr(v_key) := 'value'; -- v_key が NULL
END;
/
-- ORA-06502: null index table key value
解決
v_key := 1; -- インデックスを明示
v_arr(v_key) := 'value';
【原因⑥】EXECUTE IMMEDIATE のバインド不整合
症状
DECLARE
v_result NUMBER;
BEGIN
EXECUTE IMMEDIATE
'SELECT name FROM emp WHERE id = :1'
INTO v_result USING 100;
-- name(VARCHAR2)を v_result(NUMBER)に
END;
/
-- ORA-06502
解決
型を合わせる:
DECLARE
v_result VARCHAR2(100);
BEGIN
EXECUTE IMMEDIATE
'SELECT name FROM emp WHERE id = :1'
INTO v_result USING 100;
END;
/
【原因⑦】REF CURSOR の型不一致
症状
DECLARE
TYPE t_cursor IS REF CURSOR;
v_cursor t_cursor;
v_num NUMBER;
v_str VARCHAR2(100);
BEGIN
OPEN v_cursor FOR 'SELECT name FROM emp';
LOOP
FETCH v_cursor INTO v_num; -- ← name を数値へ
EXIT WHEN v_cursor%NOTFOUND;
END LOOP;
END;
/
-- ORA-06502
解決
FETCH v_cursor INTO v_str; -- 正しい型
【原因⑧】SQL からの戻り値型ミスマッチ
症状
DECLARE
v_id NUMBER;
BEGIN
SELECT name INTO v_id FROM emp WHERE id = 100;
END;
/
-- ORA-06502
解決
DECLARE
v_name VARCHAR2(100);
BEGIN
SELECT name INTO v_name FROM emp WHERE id = 100;
END;
/
【原因⑨】PLS_INTEGER の桁あふれ
症状
DECLARE
v PLS_INTEGER := 2147483647; -- 32bit 上限
BEGIN
v := v + 1; -- オーバーフロー
END;
/
-- ORA-01426: numeric overflow
-- 場合により ORA-06502
解決
大きな数値は NUMBER:
v NUMBER := 2147483647;
または SIMPLE_INTEGER(ラップアラウンド):
v SIMPLE_INTEGER := 2147483647;
-- +1 で -2147483648 になる(例外なし)
PLS_INTEGER 詳細は Oracle NUMBER vs INTEGER の記事も参照してください。
【原因⑩】JDBC / oracledb からのパラメータ渡し
症状
// Java 側
CallableStatement cs = conn.prepareCall("{call my_proc(?)}");
cs.setString(1, "abc"); // NUMBER パラメータに文字列
cs.execute();
// ORA-06502
診断
-- パラメータ型確認
SELECT argument_name, data_type
FROM user_arguments
WHERE object_name = 'MY_PROC';
解決
Java 側で正しい型:
cs.setInt(1, 100);
// または setBigDecimal
cs.setBigDecimal(1, new BigDecimal("100"));
PL/SQL 側でオーバーロード:
CREATE OR REPLACE PROCEDURE my_proc(p VARCHAR2) IS
BEGIN
IF VALIDATE_CONVERSION(p AS NUMBER) = 1 THEN
real_proc(TO_NUMBER(p));
ELSE
RAISE_APPLICATION_ERROR(-20001, 'Invalid number');
END IF;
END;
/
ORA-06512 スタックトレースの読み方
完全な出力例
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "SCOTT.INNER_PROC", line 24 ← 実際に発生した行
ORA-06512: at "SCOTT.OUTER_PROC", line 145 ← 呼び出し元
ORA-06512: at "SCOTT.MAIN_PROC", line 89 ← さらに呼び出し元
ORA-06512: at line 1 ← 実行位置
読み方の順序
下から上へ:
- line 1: SQL*Plus / アプリから実行
- MAIN_PROC line 89: 最初に呼ばれた
- OUTER_PROC line 145: MAIN_PROC が呼んだ
- INNER_PROC line 24: ここでエラー
該当行の確認
-- ソース確認
SELECT text FROM user_source
WHERE name = 'INNER_PROC' AND line BETWEEN 20 AND 30;
DBMS_UTILITY の活用
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK);
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
RAISE;
END;
FORMAT_ERROR_BACKTRACE で詳細トレース。
例外処理の完全リファレンス
VALUE_ERROR
ORA-06502 の全サブタイプを捕捉:
BEGIN
...
EXCEPTION
WHEN VALUE_ERROR THEN
-- 全ての ORA-06502 を捕捉
DBMS_OUTPUT.PUT_LINE('値エラー: ' || SQLERRM);
END;
INVALID_NUMBER
ORA-01722(SQL)を捕捉:
BEGIN
...
EXCEPTION
WHEN INVALID_NUMBER THEN
-- ORA-01722(SQL の数値変換失敗)
NULL;
END;
使い分け
BEGIN
v_num := TO_NUMBER(some_str); -- PL/SQL の代入 → VALUE_ERROR
-- SQL 実行
SELECT TO_NUMBER(col) INTO v_num FROM t; -- SQL → INVALID_NUMBER
EXCEPTION
WHEN VALUE_ERROR THEN ... -- PL/SQL 側
WHEN INVALID_NUMBER THEN ... -- SQL 側
END;
両方を捕捉
EXCEPTION
WHEN VALUE_ERROR OR INVALID_NUMBER THEN
-- 数値変換系エラーを全て捕捉
v_num := 0;
END;
OTHERS で全捕捉
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -6502 THEN
-- ORA-06502 の特別処理
ELSE
RAISE;
END IF;
END;
5つの解決策 完全リファレンス
解決策① 型・サイズ調整
-- サイズ拡大
v_str VARCHAR2(1000);
v_num NUMBER(10, 2);
-- または制限なし
v_num NUMBER;
解決策② 例外処理
BEGIN
v_num := TO_NUMBER(v_str);
EXCEPTION
WHEN VALUE_ERROR OR INVALID_NUMBER THEN
v_num := 0;
-- ログ記録
DBMS_OUTPUT.PUT_LINE('変換失敗: ' || v_str);
END;
解決策③ 事前バリデーション
IF VALIDATE_CONVERSION(v_str AS NUMBER) = 1 THEN
v_num := TO_NUMBER(v_str);
ELSE
v_num := 0;
END IF;
VALIDATE_CONVERSION は Oracle 12c+ で使用可能。
解決策④ PLS_INTEGER 活用
-- NUMBER の代わりに PLS_INTEGER(高速)
DECLARE
counter PLS_INTEGER := 0;
BEGIN
FOR i IN 1..1000000 LOOP
counter := counter + 1;
END LOOP;
END;
/
解決策⑤ SUBSTR で切り詰め
v_str := SUBSTR(source_str, 1, max_length);
Rails / Java / Python 対応
Rails ActiveRecord
モデル側のバリデーション(第一防衛線):
class Order < ApplicationRecord
validates :amount, numericality: true
validates :name, length: { maximum: 100 }
end
PL/SQL 呼び出しでの型安全:
# ストアド呼び出し
ActiveRecord::Base.connection.execute(
"BEGIN my_proc(:1); END;"
) do |cursor|
cursor.bind_param(1, 100, Integer) # 型明示
end
Rails 8 系の詳細は Rails 8 アップグレードガイドの記事、find/find_by/where の記事も参照してください。
Java (JDBC)
// 型を正確に指定
CallableStatement cs = conn.prepareCall("{call my_proc(?, ?)}");
cs.setBigDecimal(1, new BigDecimal("100")); // NUMBER
cs.setString(2, "hello"); // VARCHAR2
// エラーハンドリング
try {
cs.execute();
} catch (SQLException e) {
if (e.getErrorCode() == 6502) {
logger.error("PL/SQL 値エラー: " + e.getMessage());
}
}
Python (oracledb)
import oracledb
try:
cursor.callproc('my_proc', [100, 'hello'])
except oracledb.DatabaseError as e:
error_obj, = e.args
if error_obj.code == 6502:
print(f"PL/SQL 値エラー: {error_obj.message}")
実践シナリオ
シナリオ1:本番で頻発する ORA-06502 の追跡
-- ログ収集トリガー
CREATE TABLE error_log (
log_id NUMBER GENERATED ALWAYS AS IDENTITY,
error_time TIMESTAMP DEFAULT SYSTIMESTAMP,
error_code NUMBER,
error_message VARCHAR2(4000),
backtrace CLOB,
user_name VARCHAR2(50)
);
-- ハンドラ内で記録
EXCEPTION
WHEN OTHERS THEN
INSERT INTO error_log
(error_code, error_message, backtrace, user_name)
VALUES
(SQLCODE, SQLERRM,
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE,
USER);
COMMIT;
RAISE;
END;
シナリオ2:堅牢な文字列→数値変換関数
CREATE OR REPLACE FUNCTION safe_to_number(
p_str IN VARCHAR2,
p_default IN NUMBER DEFAULT NULL
) RETURN NUMBER DETERMINISTIC IS
v_result NUMBER;
BEGIN
v_result := TO_NUMBER(TRIM(p_str));
RETURN v_result;
EXCEPTION
WHEN VALUE_ERROR OR INVALID_NUMBER THEN
RETURN p_default;
END;
/
-- 使用
DECLARE
v_num NUMBER;
BEGIN
v_num := safe_to_number('abc', 0); -- 0
v_num := safe_to_number('123', 0); -- 123
END;
/
シナリオ3:VARCHAR2 の動的サイズ管理
CREATE OR REPLACE PROCEDURE safe_assign(
p_source VARCHAR2,
p_max_size PLS_INTEGER
) IS
v_target VARCHAR2(4000);
BEGIN
v_target := SUBSTR(p_source, 1, p_max_size);
-- 追加処理
EXCEPTION
WHEN VALUE_ERROR THEN
v_target := SUBSTR(p_source, 1, LEAST(LENGTH(p_source), p_max_size));
END;
/
シナリオ4:Rails からの安全な呼び出し
class OrderProcessor
def call_procedure(order_id, amount)
# 型を明示
order_id_int = order_id.to_i
amount_decimal = BigDecimal(amount.to_s)
ActiveRecord::Base.connection.exec_query(<<-SQL)
BEGIN
process_order(#{order_id_int}, #{amount_decimal});
END;
SQL
rescue ActiveRecord::StatementInvalid => e
if e.message.include?("ORA-06502")
Rails.logger.error "PL/SQL エラー: #{e.message}"
# スタックトレース抽出
end
end
end
シナリオ5:バッチ処理の堅牢化
DECLARE
CURSOR c IS SELECT id, amount_str FROM staging;
v_amount NUMBER;
v_error_count PLS_INTEGER := 0;
BEGIN
FOR rec IN c LOOP
BEGIN
v_amount := TO_NUMBER(rec.amount_str);
INSERT INTO final_data VALUES (rec.id, v_amount);
EXCEPTION
WHEN VALUE_ERROR OR INVALID_NUMBER THEN
v_error_count := v_error_count + 1;
INSERT INTO error_data VALUES (rec.id, rec.amount_str);
END;
END LOOP;
DBMS_OUTPUT.PUT_LINE('エラー: ' || v_error_count || ' 件');
COMMIT;
END;
/
シナリオ6:EXECUTE IMMEDIATE の型安全化
DECLARE
v_sql VARCHAR2(1000);
v_result CLOB; -- 汎用型
BEGIN
v_sql := 'SELECT description FROM products WHERE id = :1';
EXECUTE IMMEDIATE v_sql INTO v_result USING 100;
EXCEPTION
WHEN VALUE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('型不一致');
END;
/
シナリオ7:Solid Queue ジョブでの対処
class ProcessOrderJob < ApplicationJob
retry_on ActiveRecord::StatementInvalid, wait: 5.seconds, attempts: 3
def perform(order_id)
Order.process(order_id)
rescue ActiveRecord::StatementInvalid => e
if e.message.include?("ORA-06502")
# デッドメール送信
DeadLetterMailer.notify(e).deliver_later
end
raise
end
end
Solid Queue の詳細は Solid Queue 使い方の記事も参照してください。
シナリオ8:本番デバッグ
-- 詳細ログ
CREATE OR REPLACE PROCEDURE debug_ora_06502(p_input VARCHAR2) IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Input: ' || p_input);
DBMS_OUTPUT.PUT_LINE('Length: ' || LENGTH(p_input));
DBMS_OUTPUT.PUT_LINE('Byte Length: ' || LENGTHB(p_input));
DBMS_OUTPUT.PUT_LINE('Type: ' ||
CASE WHEN VALIDATE_CONVERSION(p_input AS NUMBER) = 1
THEN 'NUMBER' ELSE 'STRING' END);
END;
/
シナリオ9:Docker Oracle での再現
docker exec -it oracle-xe sqlplus scott/tiger <<EOF
SET SERVEROUTPUT ON
DECLARE
n NUMBER(2);
BEGIN
n := 100;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END;
/
EOF
Docker 関連は docker daemon 接続エラーの記事、Docker no space left on device の記事も参照してください。
シナリオ10:AWS RDS Oracle での対処
-- Parameter Group で例外の詳細レベル調整
-- Application 側で ORA-06502 と ORA-06512 を分離ログ
トラブルシューティング
発生位置が特定できない
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
FORMAT_ERROR_BACKTRACE で詳細スタック。
DBMS_OUTPUT が表示されない
SET SERVEROUTPUT ON
VALUE_ERROR で全て捕捉できない
サブタイプによる区別が必要な場合、SQLCODE / SQLERRM を確認:
EXCEPTION
WHEN VALUE_ERROR THEN
IF INSTR(SQLERRM, 'buffer too small') > 0 THEN
-- 文字列超過
ELSIF INSTR(SQLERRM, 'null value') > 0 THEN
-- NULL 代入
END IF;
END;
本番でしか出ない
開発: データ少、CHAR/VARCHAR2 サイズ十分
本番: データ多、限界値到達
本番相当のデータでテスト。
ORA-06512 が複数
最も深いスタック = 発生位置。最も浅い = 呼び出し元。
型不明の場合
SELECT argument_name, data_type, data_length, in_out
FROM user_arguments
WHERE object_name = 'MY_PROC'
ORDER BY position;
よくある質問(FAQ)
Q1. ORA-06502 と ORA-01722 の違い
- 06502: PL/SQL 内の広範な値エラー
- 01722: SQL の数値変換のみ
Q2. VALUE_ERROR と INVALID_NUMBER
- VALUE_ERROR: ORA-06502 全般
- INVALID_NUMBER: ORA-01722(SQL)
Q3. ORA-06512 は?
スタックトレース、必ず ORA-06502 と併発。
Q4. サブタイプの見分け方
エラーメッセージのコロン後の詳細部分:
character to number conversion error
character string buffer too small
null value not allowed
number precision too large
Q5. VARCHAR2(3 CHAR) vs VARCHAR2(3 BYTE)
- CHAR: 3文字(マルチバイトOK)
- BYTE: 3バイト(日本語は超過)
Q6. PLS_INTEGER の桁あふれ
32bit 上限(±約 21億)。超えたら NUMBER。
Q7. NOT NULL 変数の対処
IF x IS NOT NULL THEN
y := x;
END IF;
-- または NVL
y := NVL(x, 0);
Q8. Rails での対応
型を明示、ActiveModel validation で事前チェック。
Q9. スタックトレースの読み方
下から上(実行順) vs 上から下(表示順)。
Q10. パフォーマンスへの影響
例外処理は遅い。事前バリデーション推奨。
Q11. Autonomous DB での挙動
同じ。ERROR_MESSAGE_DETAILS デフォルト ON。
Q12. ORA-06502 と DBMS_LOB
LOB 関連の値エラーも ORA-06502。詳細は LOB 記事参照。
Oracle LOB(BLOB/CLOB)操作の記事も参照してください。
参考リンク
Oracle 公式
- Oracle Database Error Messages: ORA-06502
- Oracle Database Error Messages: ORA-06512
- Oracle PL/SQL Language Reference: PL/SQL Error Handling
- Oracle PL/SQL Language Reference: Predefined PL/SQL Exceptions
まとめ
ORA-06502: PL/SQL: numeric or value error の要点を再整理します。
エラーの本質
PL/SQL 内で値の代入・変換・制約違反
→ VALUE_ERROR 例外
→ ORA-06502 + ORA-06512(スタックトレース)
4種類のサブタイプ
| サブタイプ | 意味 |
|---|---|
| character to number conversion error | 文字列→数値失敗 |
| character string buffer too small | VARCHAR2 超過 |
| null value not allowed | NOT NULL に NULL |
| number precision too large | 桁あふれ |
ORA-06502 vs ORA-01722
| 項目 | ORA-06502 | ORA-01722 |
|---|---|---|
| レベル | PL/SQL | SQL |
| 範囲 | 広範 | 数値のみ |
| 例外 | VALUE_ERROR | INVALID_NUMBER |
| スタックトレース | ORA-06512 併発 | なし |
ORA-06512 スタックトレース
ORA-06502: PL/SQL: numeric or value error: ...
ORA-06512: at "SCOTT.INNER_PROC", line 24 ← 発生位置
ORA-06512: at "SCOTT.OUTER_PROC", line 145 ← 呼び出し元
ORA-06512: at line 1 ← 実行位置
読み方: 下から上(実行順)
10大原因
| # | 原因 | 対処 |
|---|---|---|
| ① | 非数値代入 | 例外処理 |
| ② | VARCHAR2 超過 | サイズ/SUBSTR |
| ③ | NOT NULL に NULL | NULL チェック |
| ④ | NUMBER 桁あふれ | 精度上げ |
| ⑤ | 配列インデックス NULL | 初期化 |
| ⑥ | EXECUTE IMMEDIATE 型 | 型明示 |
| ⑦ | REF CURSOR 型 | 型合わせ |
| ⑧ | SELECT INTO 型 | 変数型確認 |
| ⑨ | PLS_INTEGER 桁 | NUMBER 移行 |
| ⑩ | JDBC/oracledb 型 | パラメータ型明示 |
5つの解決策
-- ① 型・サイズ調整
v_str VARCHAR2(1000);
-- ② EXCEPTION 処理
EXCEPTION WHEN VALUE_ERROR THEN ...
-- ③ 事前バリデーション
IF VALIDATE_CONVERSION(...) = 1 THEN ...
-- ④ PLS_INTEGER
counter PLS_INTEGER := 0;
-- ⑤ SUBSTR
v_str := SUBSTR(source, 1, max);
例外処理
BEGIN
...
EXCEPTION
WHEN VALUE_ERROR THEN -- ORA-06502 全般
...
WHEN INVALID_NUMBER THEN -- ORA-01722(SQL)
...
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
);
RAISE;
END;
VARCHAR2 のサイズ指定
VARCHAR2(3 CHAR) -- 3文字(マルチバイトOK)
VARCHAR2(3 BYTE) -- 3バイト
VARCHAR2(3) -- NLS_LENGTH_SEMANTICS 依存
スタックトレース活用
DBMS_UTILITY.FORMAT_ERROR_STACK
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
これらの知識は、Oracle PL/SQL 開発・ストアドプロシージャ・トリガー・パッケージ・バッチ処理・Rails / Java / Python からの呼び出し・本番トラブル対応など、あらゆる場面で活用できます。本記事をブックマークしておけば、ORA-06502 に出会っても冷静に的確に対処できるようになります。
本記事は2026年6月時点の情報をもとに、Oracle Database 19c〜23ai での動作確認・公式ドキュメントに基づき作成しています。Oracle のバージョンにより挙動が異なる場合があるため、最新の情報は Oracle 公式ドキュメント(docs.oracle.com)もあわせてご確認ください。
-
前の記事
【完全ガイド】ORA-01722: invalid number の原因と解決方法|TO_NUMBER・暗黙型変換・NLS 徹底解説 2026.07.31
-
次の記事
【完全ガイド】ORA-00955: name is already used by an existing object の原因と解決方法|23ai IF NOT EXISTS・CREATE OR REPLACE 徹底解説 2026.07.31
コメントを書く