Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > JDBC: длинный литерал. Как обойти?


Автор: lazycat 27.12.2011, 15:18
Доброго времени суток всем!

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


Код

Statement targetStatement;

...

targetStatement.execute(stringVariableWithSQLInsertStatement); 


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

ORA-01704: string literal too long

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

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

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

Автор: Maksym 27.12.2011, 16:12
Вариант -- писать строку в http://en.wikipedia.org/wiki/Binary_large_object
Какая СУБД?

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


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

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


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


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


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

Добавлено через 2 минуты и 52 секунды
Можно покурить http://stackoverflow.com/questions/5549450/java-how-to-insert-clob-into-oracle-database, там несколько вариантов.

Добавлено через 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

и ниже - пример.

Автор: lazycat 27.12.2011, 17:03
По-моему, мы о разном говорим.

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


Автор: 4epT 27.12.2011, 17:13
Дело в том что есть ограничение на длину самого 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());


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

Возможно есть и другие способы.

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

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)