Oracle PreparedStatement выдает слишком большое значение из-за экранирования одинарной кавычки

Кажется, у меня проблема с пакетной вставкой 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, он просто вставляет без каких-либо проблем. И должно быть, фактическое значение по-прежнему равно 75, только одна кавычка была добавлена, чтобы избежать другой.

Каким-то образом внутренне используемый 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, оно увеличило только значение String, на котором OraclePreparedStatement выдает ошибку. Думаю, это кажется логичным.

Я знаю, что могу заменить ' на ^ или просто увеличить столбец назначения, но я не считаю эти «решения» правильным способом решения этой проблемы. Может быть, это что-то простое, чего я еще не видел?


person user768342    schedule 26.04.2012    source источник


Ответы (1)


AFAIK, я не думаю, что вам нужно справляться с побегом самостоятельно, особенно если вы используете PreparedStatement. Простое выполнение приведенных ниже действий должно позаботиться о внутреннем побеге.

pstmt.setString(paramIndex, param.getValue());
person adarshr    schedule 26.04.2012
comment
Вы так правы: / Я смотрел на эту проблему 2 часа подряд и не думал об этом. Причина в том, что я начал этот код с регулярных выражений. И постепенно изменил код в текущую форму (с PreparedStatement), часть кода (экранирующий бит) просто осталась .. И да, замена его своим кодом просто работает :) Я чувствую себя так глупо .. спасибо за открыватель глаз ! - person user768342; 26.04.2012
comment
@ user768342 Рад, что помог :) - person adarshr; 26.04.2012