2

Javaバッチ挿入に問題があるようです。Oracleテーブルに一重引用符で囲まれた値を挿入します。

java.sql.BatchUpdateException: ORA-12899: value too large for column "P40_001_CM"."PRODUCTDATA"."P_NAME" (actual: 76, maximum: 75)

実際、P_NAMEとして挿入する必要のある値は次のとおりです。

Best of Hollywood 2 Movie Collector's Pack: Todeszug nach Yuma / Recue Dawn

あなたが見ることができるように(またはあなたが好きなら数えます); これは、一重引用符を含めて、正確に75文字の長さです。

一重引用符を処理するために使用しているコードスニペット:

case Types.VARCHAR:
pstmt.setString(paramIndex, param.getValue().replace("'", "''"));
break;

このアプローチは機能し、ほとんどの挿入で機能しますが、この特定のケースでは、追加された一重引用符がカウントされ、文字列全体の長さが76になります。したがって、例外が発生します。

Squirrelでinsertステートメントを実行すると、問題なく挿入されるだけです。そして、実際の値はまだ75の長さであり、別の引用をエスケープするために1つの引用のみが追加されているはずです。

どういうわけか、内部で使用されるOraclePreparedStatementは、渡される文字列の長さに対して何らかのチェックを行い(明らかにあまり良いものではありません)、実際にOracle自体に到達する前にこれを却下します。

どうすればこれを修正できますか?この行動に出くわしたのは私だけではありませんか?

ああ、ところで、誰かが提案する前に、はい、私は試しました:

`insert into GERMANSTUFF values('Best of Hollywood 2 Movie Collector'||chr(39)||'s Pack: Todeszug nach Zuma / Recue Dawn');`

insert into GERMANSTUFF values(translate('Best of Hollywood 2 Movie Collector^s Pack: Todeszug nach Puma / Recue Dawn','^',chr(39)));

これはSquirrelでは直接SQLステートメントとして機能しますが、OraclePreparedStatementがエラーをスローするString値を大きくするだけです。これは論理的に思えます。

をに置き換えるか、宛先列を拡大するだけでよいことはわかってい'ます^が、これらの「解決策」をこの問題を解決する正しい方法とは考えていません。多分それは私がまだ見たことがない単純なものですか?

4

1 に答える 1

8

AFAIK、特にを使用している場合は、エスケープを自分で処理する必要はないと思いますPreparedStatement。以下を実行するだけで、内部でのエスケープを処理する必要があります。

pstmt.setString(paramIndex, param.getValue());
于 2012-04-26T13:51:30.220 に答える