プラットフォーム移行時のトラブル

ORA-12899: 列 string の値が大きすぎます(実際: string、最大: string)

この問題の多くは異なるプラットフォームの間でデータをやり取りするときに発生する。(特に Windows から Unix 系への インポート処理 の場合)

  • エクスポートしたデータのインポート
  • データベースリンクを使用した INSERT
  • CHAR 型を使用した文字列結合

が主な発生するタイミングである。

原因

データの提供元のキャラクタセットと投入先のデータベース・キャラクタセットにおいて、同じ文字でもバイト数が異なる文字列を使用している。
その代表が半角カタカタである。 Shift JIS の場合、半角カタカナは 'A6'x 〜 'DF'x で 1 バイトで格納できるが、EUC-JP の場合 '8E26'x 〜 '8E5F'x と長さは 2 バイトになる。同様に UTF-8 なら 3 バイト、UTF-16 なら 2 バイトになる。

対応

根本的な解決は、移行先のテーブル定義を変更する。このエラーがでるということは、テーブル定義の列定義がバイト・セマンティクス表記であるはずなので、そのバイトサイズを大きくする。その大きさは各キャラクタセットにおける1文字の最大サイズ×キャラクタ数を設定する。
または、キャラクタ・セマンティクスで列定義 Oracle 9i を行なう。

原因

CHAR 型を使用した文字列結合について誤解している可能性がある。

対応

例えば CHAR(100)と定義されたカラム(変数も同様)に対して 'ABC' を代入するとカラムは 'ABC' + スペース 97個 になる。
例えば CHAR(100)の COL100 カラムに 'ABC' を設定した後 UPDATE .. SET COL100 = COL100 || 'DEF' は 'ABC' + 'DEF' = 'ABCDEF' ではなく 'ABC' + スペース 97個 + 'DEF' になる。 CHAR(100) に代入することはできない。RTRIM 関数やなどを利用する必要がある。
但し 'ABC_' + 'DEF' = 'ABC_DEF' を期待しても結果は 'ABCDEF' になる。('_' はスペース)

CHAR 型の文字列結合のエラー例

SQL> create table char_len(col100 char(100));
表が作成されました。
 
SQL> insert into char_len values('abc');
1行が作成されました。
 
SQL> update char_len set col100 = col100 || 'def';
update char_len set col100 = col100 || 'def'
                                     *
行1でエラーが発生しました。:
ORA-12899: 列"SYS"."CHAR_LEN"."COL100"の値が大きすぎます(実際: 103、最大: 100)

変数の場合でも同様であるがエラーメッセージが異なる PL/SQL の場合には
「ORA-06502: PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます。が発生しました」 が発生する。

SQL> set serveroutput on
SQL> declare
  2     vMoji100 CHAR(100);
  3  begin
  4     vMoji100 := 'ABC';
  5     dbms_output.put_line('vMoji Leng=' || lengthb(vMoji100 || 'DEF'));
  6     vMoji100 := vMoji100 || 'DEF';
  7  end;
  8  /
vMoji Leng=103   ← 103 バイトになる
declare
*
行1でエラーが発生しました。:
ORA-06502: PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます。が発生しました
ORA-06512: 行6


関連事項

一覧ページへ戻る

OTN (Oracle Technology Network)によるエラーメッセージによる情報だけでは、対処に困ったエラーについてのプラクティスです。
ベスト・プラクティスというわけではないので、書いてあることに固執しないで広い視野でエラー対応してください。

ORA-12899の関連トピックス

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ Oracle のライセンスがわからない…
Oracle Direct (ネットで聞いても最後はここで要確認)