我想模仿許多數據庫在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)。我知道Oracle和Postgres都支持插入的RETURNING子句,通常這是如何處理的。但是,我沒有看到OpenEdge這樣的東西。
我在10.2B SQL開發手冊中可以找到的唯一相關部分是5-10節,其中顯示了在執行使用NEXTVAL
的INSERT
之後如何訪問序列的CURRVAL
。但是,如果跨多個JDBC會話(競爭條件和其他事件)有大量INSERT
正在進行該表,那麼這很危險,因爲我可以獲取其他人的ID。
到目前爲止我唯一可以提出的方法是編寫一個專門用於包裝/執行INSERT
操作的存儲過程,該操作具有生成的ID的輸出參數。然而,對於我正在處理的內容來說,這是不可行的,它必須使用普通的SQL INSERT
語句,並且看起來也有點瑣碎和脆弱(例如,如何處理可能提供的值的不同組合和排列INSERT
,如果模式改變?)。
另外,這裏的要點是不必在INSERT中引用主鍵,所以請不要告訴我在我的INSERT
語句中使用users_seq.NEXTVAL
。 :-)
它是一種適用於不同語言的數據庫適配器,因此整個過程根本就不在ABL中。 :-) – 2012-05-15 13:04:02
祝你好運! :)) – firhang 2012-05-15 14:25:14
謝謝!我應該有更多時間在下週開始工作。我們會看到它結束了。 – 2012-05-15 14:41:49