Невозможно обновить таблицу Oracle IOT с помощью метода jbdc updateRow - PullRequest
4 голосов
/ 02 марта 2010

У меня есть база данных Oracle 10gR2 с таблицей IOT в пределах:

create table countries (
 id number primary key, 
 name varchar2(30) not null enable
) organization index;

Я пытаюсь обновить табличные значения с помощью этого кода Java (версия 1.6):

Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
                  ResultSet.CONCUR_UPDATABLE);

ResultSet src = stmt.executeQuery("select id, name from countries");

src.next();

src.updateString("name", "__test__");
src.updateRow();

Но updateRow генерирует исключение SQLException (ORA-01410: неверный ROWID). Если я попытаюсь обновить кучу (обычную) таблицу - все работает.

Я использую этот код с различными версиями драйверов оракула (отсюда http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc_10201.html)

После некоторых исследований я обнаружил, что таблицы IOT и HEAP имеют разный формат строк:

Пример IOT * BAJzKgwCwRb +

Пример HEAP AAAbgVAAJAAMyr8AAA

Но я до сих пор не знаю, как решить эту проблему. У вас есть идеи?

Ответы [ 2 ]

1 голос
/ 02 марта 2010

Похоже, ваш стол не обязательно должен быть IOT. Я бы посоветовал вам воссоздать ее как обычную таблицу и добавить индекс по ИД и имени. Та же производительность, та же логика, без проблем ROWID.

1 голос
/ 02 марта 2010

Можете ли вы получить результаты расширенной трассировки SQL вашего запроса, чтобы увидеть, что JDBC делает под прикрытием? Я подозреваю, что он пытается сделать

UPDATE COUNTRIES SET NAME = '__TEST__' WHERE ROWID = :rowid_fetched

и ROWID означает что-то совершенно другое в Oracle IOT; это не неизменный адрес строки, а предположение относительно пути к строке.

Моя рекомендация относительно того, как это сделать, заключается в том, чтобы распространить сгенерированное системой поле отметки времени на все ваши таблицы и использовать его для управления параллелизмом, а не для объявления обновляемого набора записей - который будет принимать и удерживать блокировки для каждой записи в набор записей.

Тогда ваше приложение будет извлекать набор строк как обычно, но выдает операторы вроде:

UPDATE COUNTRIES SET NAME = '__TEST__' WHERE MOD_TS = :mod_ts_fetched

для создания оптимистической блокировки без сохранения состояния.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...