我有一个带有IOT表的Oracle 10gR2数据库:
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).如果我尝试更新堆(普通)表 – 一切正常.
我用不同版本的oracle驱动程序使用此代码(从这里http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc_10201.html)
经过一些研究后,我发现IOT和HEAP表有不同的rowid格式:
物联网示例 BAJzKgwCwRb
HEAP示例AAAbgVAAJAAMyr8AAA
但我还是不知道如何解决这个问题.你有什么想法吗?
最佳答案 您是否可以获得查询的扩展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
给予无国籍乐观锁定.