2012-03-17 102 views
1

我想模仿許多數據庫在OpenEdge中具有的自動遞增主鍵功能(即,在執行操作時不必指定主鍵值INSERT)使用JDBC適配器。到目前爲止,我已經非常接近我需要的東西了,除了能夠訪問數據庫從INSERT返回時生成的主鍵值的部分(可能不是那麼近)。正確使用SQL/JDBC在OpenEdge 10.2B中正確實現自動遞增主鍵

我目前的解決方案採用表PK默認值,觸發器和序列的組合,以把它關閉:

CREATE TABLE users (
    id BIGINT PRIMARY KEY DEFAULT -1, 
    name VARCHAR(200) 
); 

CREATE SEQUENCE users_seq 
START WITH 0, 
INCREMENT BY 1, 
NOCYCLE; 

CREATE TRIGGER users_trigger 
BEFORE INSERT ON users 
REFERENCING NEWROW 
FOR EACH ROW 
IMPORT 
import java.sql.*; 
BEGIN 
Long current_id = (Long)NEWROW.getValue(1, BIGINT); 
if (current_id == -1) { 
    SQLCursor next_id_query = new SQLCursor("SELECT TOP 1 users_seq.NEXTVAL FROM SYSPROGRESS.SYSCALCTABLE"); 
    next_id_query.open(); 
    next_id_query.fetch(); 
    Long next_id = (Long)next_id_query.getValue(1,BIGINT); 
    next_id_query.close(); 
    NEWROW.setValue(1, next_id); 
} 
END 

這讓我運行一個INSERT語句是這樣的:

INSERT INTO users(name) VALUES('Foo Bar') 

並且新行自動從數據庫觸發器獲取ID。這部分工作正常。

我現在真正需要的是設置ID的值;或者直接獲取值,或者是包含剛剛插入的行的ResultSet(然後可以解包以查看ID)。我知道OraclePostgres都支持插入的RETURNING子句,通常這是如何處理的。但是,我沒有看到OpenEdge這樣的東西。

我在10.2B SQL開發手冊中可以找到的唯一相關部分是5-10節,其中顯示了在執行使用NEXTVALINSERT之後如何訪問序列的CURRVAL。但是,如果跨多個JDBC會話(競爭條件和其他事件)有大量INSERT正在進行該表,那麼這很危險,因爲我可以獲取其他人的ID。

到目前爲止我唯一可以提出的方法是編寫一個專門用於包裝/執行INSERT操作的存儲過程,該操作具有生成的ID的輸出參數。然而,對於我正在處理的內容來說,這是不可行的,它必須使用普通的SQL INSERT語句,並且看起來也有點瑣碎和脆弱(例如,如何處理可能提供的值的不同組合和排列INSERT,如果模式改變?)。

另外,這裏的要點是不必在INSERT中引用主鍵,所以請不要告訴我在我的INSERT語句中使用users_seq.NEXTVAL。 :-)

回答

1

有沒有可行的方法來實現這一點;用戶必須指定PK的值或指定序列的名稱,以便可以使用CURRVAL/NEXTVAL

一個不可行的解決方法是構造一個專門用於執行INSERT的特殊存儲過程,但這不是一個通用的解決方案,因爲INSERT命令需要可變數量的參數(其中最重要的是哪些列和數據以填充),而存儲過程必須具有固定數量的參數。

如果存在一個SQL函數,它將返回一個與客戶端與SQL引擎的瞬時連接相對應的特殊會話ID,那麼客戶端和觸發器/存儲過程可以使用預定義的表進行通信請求隊列(通過使用會話ID作爲關鍵字)。不幸的是,根據文檔沒有這樣的會話ID。

-2

1個愚蠢的問題......爲什麼你用這個SQL代碼來更新Data in Progress DB? 它在4GL(或ABL)代碼中變得更容易了......您應該在應用服務器上創建一個簡單的創建過程或服務。 我有一個遷移工具(勺子)的ODBC SQL訪問問題。我必須放棄...

+0

它是一種適用於不同語言的數據庫適配器,因此整個過程根本就不在ABL中。 :-) – 2012-05-15 13:04:02

+0

祝你好運! :)) – firhang 2012-05-15 14:25:14

+0

謝謝!我應該有更多時間在下週開始工作。我們會看到它結束了。 – 2012-05-15 14:41:49