【完全ガイド】ORA-06502: PL/SQL numeric or value error の原因と解決方法|4種類のサブタイプ・NOT NULL・例外処理 徹底解説

【完全ガイド】ORA-06502: PL/SQL numeric or value error の原因と解決方法|4種類のサブタイプ・NOT NULL・例外処理 徹底解説

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_ERROR vs INVALID_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 を根本から解決できるようになります。


目次

結論:4種類のサブタイプを理解

時間がない方向けに、最速の対処を先に示します。

4種類のサブタイプ

サブタイプ意味
character to number conversion error文字列→数値失敗n := 'abc'
character string buffer too smallVARCHAR2 長さ超過v3 := 'abcde' (v3 は VARCHAR2(3))
null value not allowedNOT NULL に NULLn1 := 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-06502ORA-01722
レベルPL/SQLSQL
範囲広範な値エラー数値変換のみ
例外名VALUE_ERRORINVALID_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                          ← 実行位置

読み方の順序

下から上へ:

  1. line 1: SQL*Plus / アプリから実行
  2. MAIN_PROC line 89: 最初に呼ばれた
  3. OUTER_PROC line 145: MAIN_PROC が呼んだ
  4. 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 公式


まとめ

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 smallVARCHAR2 超過
null value not allowedNOT NULL に NULL
number precision too large桁あふれ

ORA-06502 vs ORA-01722

項目ORA-06502ORA-01722
レベルPL/SQLSQL
範囲広範数値のみ
例外VALUE_ERRORINVALID_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 に NULLNULL チェック
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)もあわせてご確認ください。