Oracle

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 809
21
#1
Теряю веру в жизнь :(

Есть агент, который инсертит данные в базу Oracle.
В запросе 32 параметра. Заполняются через PreparedStatement.
Инсерт происходит через executeBatch();
В итоге получаю ошибку:
java.sql.BatchUpdateException: ORA-12899: value too large for column "PERSONAL_ACCOUNT" (actual: 138, maximum: 30)
Но что самое интересное - данные, которые я пытаюсь вставить в это поле, меньше 30.
Подскажите, как просмотреть SQL-запрос, который образовался после подготовки?
Мне кажется, что проблема именно в нем.

Такой вариант не работает. Ппринтует только указатель
Java:
System.out.println(preparedStatement);
 
Последнее редактирование модератором:

garrick

Lotus team
26.10.2009
901
61
#2
Spring JDBC умеет это. Но у оракловых драйверов есть свои встроенные средства логирования (не пробовал)
Для просмотра контента необходимо: Войти или зарегистрироваться
, только драйвера надо с буквой _g использовать.
  1. Разница в видимом вами количестве символов и реально вставляемым в базу может быть из-за разных кодировок.
  2. Убедитесь, что "вставляете" в ту схему, структуру таблицы которой вы смотрите, не полагайтесь на схему по-умолчанию, укажие её явно.
  3. Ну, и в конце-концов есть же отладка "по-шагам" (в какой-нибудь Java IDE). Посмотрите что у ваc там вставляется в это поле.
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 809
21
#3
1. Кодировка приведена к UTF-8 как и сама таблица. Строку в байтах привожу к допустимой длине поля (-2 байта для хеша).
Так что в принципе такой ошибки быть не должно.
2. таблица та.
3. с отладкой проблема :( Пытаюсь решить, но пока никак
 

garrick

Lotus team
26.10.2009
901
61
#6
1. Кодировка приведена к UTF-8 как и сама таблица. Строку в байтах привожу к допустимой длине поля (-2 байта для хеша).
Так что в принципе такой ошибки быть не должно.
Код:
SELECT * FROM nls_database_parameters;
что говорит?
Не таблица, а схема. В другой схеме может быть таблица с таким же именем.
3. с отладкой проблема :( Пытаюсь решить, но пока никак
А какие трудности?
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 809
21
#7
этот вопрос снят.
Тяжело быть бестолковым. Спутал индексы параметров запроса.

Но появился другой вопрос. Необходимо по индексу определить имя параметра.
Запрос следующего вида
Код:
INSERT INTO table( fld1, fld2, fld3 )
VALUES ( ?, ?, ?)
Пробовал так :
Java:
ParameterMetaData paramMetaData = queryOra.getParameterMetaData();
String paramTypeName = paramMetaData.getParameterTypeName(1);
Но безрезультатно :(
Хотя paramMetaData в принципе есть. Количество параметров получить можно
 
Последнее редактирование модератором:

garrick

Lotus team
26.10.2009
901
61
#8
Не могу придумать зачем это может понадобиться.
Но может быть тогда уже сразу перейти к именованным параметрам?
Код:
ps = conn.prepareStatement("select * from tab where id = :id");
((OraclePreparedStatement)ps).setIntByName("id", 42);
или опять же Spring
Для просмотра контента необходимо: Войти или зарегистрироваться
 
Последнее редактирование модератором:

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 809
21
#10
Не могу придумать зачем это может понадобиться.
Но может быть тогда уже сразу перейти к именованным параметрам?
Код:
ps = conn.prepareStatement("select * from tab where id = :id");
((OraclePreparedStatement)ps).setIntByName("id", 42);
или опять же Spring
Для просмотра контента необходимо: Войти или зарегистрироваться
Могу сказать. Очень удобно, когда запросы пишет кто-то другой.
При обращении по индексу поля должны мапиться в определенном порядке. Иначе будет как у меня :)
Спутал порядок - получил ошибку.
Да я собвственно и не против обращаться по индексу, но мне нужно знать имя параметра
 

garrick

Lotus team
26.10.2009
901
61
#11
Код:
ParameterMetaData
Возвращает только тип параметра, например INTEGER, VARCHAR & etc., но не имя столбца.
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 809
21
#12
в общем разобрался.
Пришлось писать парсер и параметры в запросе указывать в виде
Код:
:<имя параметра>
 

garrick

Lotus team
26.10.2009
901
61
#13
А на паркуа? Чем Spring JDBC Template не устроило? Там уже это есть готовое + много ещё чего интересного. К тому же, как я уже указывал выше, в оракловом JDBC драйвере уже есть методы setXXXAtName()*. Например:
Код:
void setStringAtName(String parameterName,
					 String value)
					 throws SQLException
Код:
OraclePreparedStatement ps = conn.prepareStatement("select * from tab where name = :name");
ps.setStringAtName("name", "Bob");
* - XXX - это Int, String, Date & etc.
 
Последнее редактирование модератором: