2010-03-02 24 views
4

我在Oracle 10gR2數據庫與IOT表:不能與JBDC updateRow方法更新的Oracle IOT表

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

我嘗試用這種爪哇(版本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:invalid ROWID)。如果我嘗試更新堆(普通)表 - 所有作品。

我使用此代碼與不同版本的Oracle驅動程序(從這裏http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc_10201.html

經過一番研究,我已經檢測到物聯網和HEAP表具有的rowid的不同格式:

IOT例如* BAJzKgwCwRb +

HEAP示例AAAbgVAAJAAMyr8AAA

但是我仍然不知道如何解決這個問題。你有什麼想法嗎?

回答

1

您可以獲得查詢的擴展SQL跟蹤的結果,以查看JDBC在封面下正在執行的操作嗎?我懷疑這是試圖做

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

和ROWID意味着甲骨文IOT的完全不同的東西;它不是一行的不可變地址,而是對行的路徑的猜測。

我對如何做到這一點的建議是將系統生成的時間戳字段傳播到您的所有表上,並將其用於併發控制,而不是聲明可更新的記錄集 - 它將佔用並保存每條記錄的鎖在記錄集中。

那麼你的應用程序將獲取行集爲正常,但問題之類的語句:

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

給無國籍樂觀鎖。

+0

跟蹤是個好主意!謝謝! 關於您的解決方法的想法:謝謝,但我不需要解決方法,我想了解爲什麼它不起作用。這是一個錯誤或實施限制或只是我的錯誤。 – glebreutov 2010-03-02 16:40:24

1

看起來你的桌子並不需要是物聯網。我建議你重新創建它作爲一個普通的表,並添加ID和名稱的索引。相同的性能,相同的邏輯,沒有ROWID問題。

+0

感謝您的解決方法,但我想了解爲什麼它不起作用。這是一個錯誤或實施限制或只是我的錯誤。 – glebreutov 2010-03-02 16:31:34

+0

我沒有用過Java,但可能有一個設置在「UPDATE BY ROWID」和「UPDATE BY PRIMARY KEY」之間切換。 – jva 2010-03-03 07:48:45