Skip to content

Instantly share code, notes, and snippets.

@tmd45
Created June 1, 2012 13:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmd45/2852172 to your computer and use it in GitHub Desktop.
Save tmd45/2852172 to your computer and use it in GitHub Desktop.
Cutting by byte, MS932 character. After, insert this String to Oracle DB by jdbc, whereupon get ORA-12899
/** 分割開始インデックス */
static final int DIVISION_BYTE_START_INDEX = 0;
/** 分割後文字長 */
static final int DIVISION_BYTE_LENGTH_ADDR = 48;
/**
* 引数の文字列を[分割後文字長(byte)]以下にカットする。<br>
* 扱う文字コードは MS932 とする。
*
* @param str 文字列(MS932)
* @return String [分割後文字長(byte)]以下の文字列
*/
String getDivideStringByByte(String str) {
if(str == null) {
return null;
}
String result = "";
try {
// バイト配列化
byte[] byteAddr = address.getBytes("MS932");
if(byteAddr.length > DIVISION_BYTE_START_INDEX) {
// byte文字列が分割開始インデックス以上の長さである
if(byteAddr.length > DIVISION_BYTE_START_INDEX + DIVISION_BYTE_LENGTH_ADDR) {
// byte文字列が分割したい文字長以上の長さである
result = new String(byteAddr,
DIVISION_BYTE_START_INDEX,
DIVISION_BYTE_LENGTH_ADDR,
"MS932").trim();
} else {
// 必要文字長に満たない場合
result = new String(byteAddr,
DIVISION_BYTE_START_INDEX,
byteAddr.length - DIVISION_BYTE_START_INDEX, // 長さ:文字長 - 分割(開始)位置
"MS932").trim();
}
// いわゆる“おまじない”コード(恥)
// result = new String(result.getBytes("MS932"));
} catch(UnsupportedEncodingException ue) {
throw new IllegalArgumentException(ue);
}
return result;
}
}
@tmd45
Copy link
Author

tmd45 commented Jun 1, 2012

引数の文字列において、分割される文字列に半角文字(1byte文字)を含むと、切り口(47-48byte)の文字がぶった切られて文字化けする。
例:

"あい うえおかき" → 10 byteで分割 → "あい うえ?"

これをそのままデータベース(oracle)へ insert しようとしたところ、ORA-12899 エラーになった。

カラムに定義された文字長=分割文字長であり、たとえば上記の例であれば:

ORA-12899: 列"DEV"."HOGETABLE"."COLUMN1"の値が大きすぎます(実際: 11、最大: 10)

JDBC(ojdbc14)で insert する直前の値を確認したとき、以下の2パターンが存在した。
前者は末尾の文字が全角の「?」になっている:

1) あい うえ?
2) あい うえ?

1 の場合に ORA-12899 エラーが発生している。

1 は、上記のコードで生成された文字列を用いている。
2 は、上記のコードの おまじない を有効にした場合の文字列を用いている。

1 と 2 の文字列は、(JDBCへ渡す前は)全く同じ文字列に見える:

1) あい うえ? → byte化(MS932):82 a0 82 a2 20 82 a4 82
2) あい うえ? → byte化(MS932):82 a0 82 a2 20 82 a4 82

しかし、String#equals で比較すると「異なる」と判断される。
String#equals は各文字を char で比較する。char にしたときの各文字は 以下のようになる:

1) 'あ' 'い' ' ' 'う' 'え' '・'
2) 'あ' 'い' ' ' 'う' 'え' '?'

上記の正しい理由と正しい解決方法を模索中。。。

@tmd45
Copy link
Author

tmd45 commented Jun 1, 2012

ちなみにデータベースの文字コードは Shift_JIS(JA16SJISTILDE)。

@tmd45
Copy link
Author

tmd45 commented Jun 1, 2012

当初は Shift_JIS と MS932 の文字の問題でよくある「~」とか「-」のせいだと思って調査していたが違ったんだぜ、っていう紆余曲折。

@tmd45
Copy link
Author

tmd45 commented Jun 1, 2012

JDK 1.5.0_12

@tmd45
Copy link
Author

tmd45 commented Jun 2, 2012

Qiita に突っ込んできた。 http://qiita.com/items/fa7e4fdbd4f7ad9a29ae

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment