Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> JDBC: длинный литерал. Как обойти? ORA-01704: string literal too long 
:(
    Опции темы
lazycat
Дата 27.12.2011, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 15.7.2007

Репутация: 1
Всего: 1



Доброго времени суток всем!

При попытке записи в базу:


Код

Statement targetStatement;

...

targetStatement.execute(stringVariableWithSQLInsertStatement); 


получаю исключение.

ORA-01704: string literal too long

Действительно, длина строки 17К, более чем в 4 раза превышает допустимые 4000 символов, но

Есть ли возможность это обойти?
(Я уверен, что есть, иначе как бы записывались длинные записи?)

Заранее благодарен всем откликнувшимся!

PM MAIL   Вверх
Maksym
Дата 27.12.2011, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


.
***


Профиль
Группа: Участник Клуба
Сообщений: 1456
Регистрация: 19.8.2005
Где: Odessa, Black Sea

Репутация: 14
Всего: 62



Вариант -- писать строку в BLOB
Какая СУБД?
PM MAIL   Вверх
lazycat
Дата 27.12.2011, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 15.7.2007

Репутация: 1
Всего: 1



Цитата(Maksym @  27.12.2011,  16:12 Найти цитируемый пост)
Какая СУБД? 


Прошу прощения, забыл сказать. СУБД - Oracle. Указываю

"jdbc:oracle:thin:@адрес:порт:схема"


Цитата(Maksym @  27.12.2011,  16:12 Найти цитируемый пост)
Вариант -- писать строку в BLOB 


У меня CLOB, но это несущественно. 
Я бы рад писать в CLOB, но как это сделать? Или execute() / executeUpdate() - это не единственный вариант записи?


PM MAIL   Вверх
Maksym
Дата 27.12.2011, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


.
***


Профиль
Группа: Участник Клуба
Сообщений: 1456
Регистрация: 19.8.2005
Где: Odessa, Black Sea

Репутация: 14
Всего: 62



Насколько я помню, данные в CLOB пишутся через поток. Сейчас поищу пример

Добавлено через 2 минуты и 52 секунды
Можно покурить обсуждение, там несколько вариантов.

Добавлено через 5 минут и 25 секунд
Основная мысль там:
Цитата

The main point: Unlike with other JDBC drivers, the one from Oracle doesn't support using Reader and InputStream as parameters of an INSERT. Instead, you must SELECT the CLOB column FOR UPDATE and then write into the ResultSet

и ниже - пример.
PM MAIL   Вверх
lazycat
Дата 27.12.2011, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 15.7.2007

Репутация: 1
Всего: 1



По-моему, мы о разном говорим.

У меня есть база, мне надо инсертить в таблицу.
Формирую строку с SQL-запросом INSERT. Строка получается 17K длиной. Метод execute вываливается по исключению "слишком длинная строка". 
Я в упор не могу понять, где здесь место CLOBу или BLOBу. То, что одно из полей у меня CLOB никак не отменяет тот факт, что в методах execute() параметр только типа String.


PM MAIL   Вверх
4epT
Дата 27.12.2011, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Дело в том что есть ограничение на длину самого insert ... такой insert нужно сделать через select for update.

Вот пример:

Код

conn = getConnection("saveClob");
            
stmt = (OraclePreparedStatement) conn.prepareStatement("SELECT " + fieldName + " FROM " + tableName + " WHERE ID = ? FOR
UPDATE");
stmt.setInt(1, id);
rs = (OracleResultSet) stmt.executeQuery();
rs.next();
request = rs.getCLOB(1);
pw = new PrintWriter(request.getCharacterOutputStream());
pw.write(data);
pw.flush();
            
conn.commit();
rs.close();
pw.close();
stmt.close();


fieldName - имя столбца CLOB, tableName - имя таблицы, id - номер поля в которое сохраняешь CLOB

Естественно перед сохранением нужно сделать insert с пустым CLOB:

Код

insert into cc(id, clob_data) values(1, EMPTY_CLOB());


Данный код работает) проверено ...

Возможно есть и другие способы.
PM MAIL   Вверх
lazycat
Дата 28.12.2011, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 15.7.2007

Репутация: 1
Всего: 1



Огромное спасибо Maksym и 4epT (в особенности 4epT !!!) за помощь !!!
 
Подход "создать запись а затем обновить в нем CLOB" прекрасно работает.

Кстати, в данном случае возиться с потоком совсем не обязательно. Объект Clob не накладывает ограничение на длину строки, поэтому вполне можно применять метод setString(), что я и сделал.

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0815 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.