新しくブログを開設しました。

Webエンジニアがデザイナーになってみる。


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

新しくブログを開設しました。

Webエンジニアがデザイナーになってみる。


Java.sql.PreparedStatementインターフェースを使用してOracleデータベースにデータを登録する際、setString()メソッドを使用してバインドできる文字列のサイズには制限があるようです。

Oracleデータベースとしてのバインドサイズの上限はVARCHAR2、NVARCHAR2の最大サイズ(4000バイト)と同じなのですが、Oracle JDBCドライバでPreparedStatementインターフェースのsetString()メソッドを使用した場合、使用しているキャラクタ・セットによってより厳しいサイズ制限が課せられるようです。

「Oracle9i JDBC開発者ガイドおよびリファレンス2(9.2)」の中の「ThinドライバによるSQL CHAR データ・サイズ制限」というトピックで解説されている内容を見ると、データベース・キャラクタセットがJA16SJISの場合、2000バイト(UTF-8バイト)が上限となっています。

つまり、文字数で言うと日本語ばかりで666文字(UTF-8では日本語は3バイトで表される)が上限となるというわけです。

※なぜUTF-8が出てくるのかと言うと、Oracle JDBCドライバは、CHAR またはVARCHAR2 バインドのために、Java UTF-16キャラクタをUTF-8エンコーディング・バイトに変換し、次にUTF-8 エンコーディング・バイトはデータベースに転送され、データベースはUTF-8 エンコーディング・バイトをデータベース・キャラクタ・セット・エンコーディングに変換するという内部的な仕組みになっているためです。

この制限を超える文字列をsetString()によってバインドしようとした場合は
ORA-17070: データ・サイズがこの型の最大サイズを超えています。
というエラーが発生します。

このエラーを回避するためには、日本語で666文字を超えるような値をセットされる可能性のある文字列型の列に対しては、setString()ではなく、setCharacterStream()を使用して値をバインドする必要があります。




まじやっかい。。
こんな制限かけんなよ><
varchar2(4000)になってんのに2000バイトまでしかINSERTできないってさー


しかも、setCharacterStream()を使用しても1テーブル内に大きな数のカラムが2つ以上ある場合は、正常にバインドされないんだとさ。
1つのテーブルにLONG型みたいなでかい数のカラムは存在できないってことらしいよ。
全然しらなかったけどさ。


ちなみにもう一つの解決方法は、日本語はJAVAのUTF-8では3byteでカウントされしまうから666文字までしか入らないんだな。だから2000バイトまでの文字列に分割して(a||b||c||d)みたいにSQL内でバインドさせるといいらしいよ。

スポンサーサイト

テーマ:Linux - ジャンル:コンピュータ

<<VARCHAR2へ文字列をバインドするための対処法探しの旅 | ホーム | 口パクの正体は・・・!?>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://kanamehackday.blog17.fc2.com/tb.php/96-56ba1f0e
この記事にトラックバックする(FC2ブログユーザー)
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。