在DB2

2016-10-08 24 views
0

創建從一個共享序列主鍵我想在DB2(10.5 LUW)使用單個序列的所有主鍵。在DB2

但是我瞎了雙眼沒有設法找到一個方法來做到這一點..最近我可以是使用功能,但是當多個值插入到相同的語句失敗。這是因爲該功能只被評估一次。可以通過添加列值的依賴來調整,但不喜歡這樣做。

The question relates to my previous one

CREATE SEQUENCE TEST.ID_SEQ AS BIGINT START WITH 10000 INCREMENT BY 1 NO MAXVALUE NO CYCLE CACHE 100 
GO 
--- Bad "hack" since the function is not deterministic 
--- see comments below 
CREATE OR REPLACE FUNCTION TEST.OBJECT_ID() 
    RETURNS BIGINT SPECIFIC TEST.OBJECT_ID 
    CONTAINS SQL DETERMINISTIC NO EXTERNAL ACTION 
    BEGIN 
    DECLARE B BIGINT; 
    SET B = NEXT VALUE FOR TEST.ID_SEQ ; 
    RETURN B ; 
    END 
GO 

CREATE TABLE TEST.TEST (
    ID BIGINT  NOT NULL PRIMARY KEY GENERATED ALWAYS AS (TEST.OBJECT_ID()), 
    TEST VARCHAR(10) 
) 
GO 
+0

你爲什麼要這麼做?我的意思是,對於所有主鍵,單個序列對我來說不是一個好主意,因爲它將成爲熱點。 – MichaelTiefenbacher

+0

我想有一個唯一的ID爲所有實體。同樣以這種方式,開發人員不能將錯誤的外鍵(其他表的pk)插入表中,因爲鍵只存在一次。 – JMX

+0

首先,你的函數是不確定的,因爲它永遠不會返回相同的值。但是那不重要 - 你的整個方法似乎是錯誤的。 – mustaccio

回答

0

您可以使用自動增量

create table TEST.TEST (
id integer not null GENERATED ALWAYS AS IDENTITY (START WITH 10000 INCREMENT BY 1) 
,TEST varchar(30) 
,PRIMARY KEY (id) 
); 

或使用插入這樣

INSERT INTO ORDERS (ORDERNO, CUSTNO) VALUES (NEXT VALUE FOR ORDER_SEQ, 12) 
+0

感謝您的回覆。我實際上希望從相同的序列中獲取所有ids,以便主鍵在表中唯一。其他表中不存在相同的pk。 – JMX

+0

我同意MichaelTiefenbacher,這不是一個好意思。你說:「也是這樣,開發人員不能將錯誤的外鍵(其他表的pk)插入到表中,因爲這些鍵只存在一次」,但是如果在所有主鍵上創建自動增量,則不會出現此問題,系統將管理密鑰 – Esperento57

+0

是的,他們可以,因爲表具有相同的運行數字,在這種情況下從10000開始....當然,在單個表中,ID是唯一的,但在整個實現中並不唯一(罕見情況,但相當容易使用pk從錯誤的表中取出)。從緩存序列中獲取ID也是相當快的操作。在我的情況下,熱點不是問題。 – JMX

0

的腳本,給什麼就足夠了榜樣有一個表作爲一個用於多個TABLE的父項[顯示兩個子表,每個都有相同 INSERT TRIGGER],橫跨每個將具有從剛好一個分配的下一序列值,從而共享 SEQUENCE。當然,家長將得到每一個序列值,和每個孩子將得到只有那些沒有在任何其他子表值:

drop table AppFile01 ; 
drop table AppFile02 ; 
drop table Master_IDENTITY ; 
drop sequence  ID_SEQ ;  

create table Master_IDENTITY 
(Master_ID BIGINT NOT NULL 
, constraint Master_IDENTITY_PK 
    PRIMARY KEY (Master_ID) 
) 
; 
CREATE SEQUENCE  ID_SEQ AS BIGINT 
    START WITH 10000 INCREMENT BY 1  
    NO MAXVALUE NO CYCLE CACHE 100  
; 
create table AppFile01 
(sKeyAF  BIGINT  not null  
, ts   timestamp default current timestamp 
, constraint AppFile01_PK  
    PRIMARY KEY (sKeyAF)  
, constraint AppFile01_FK  
    FOREIGN KEY (sKeyAF)  
    REFERENCES Master_IDENTITY (Master_ID) 
    ON DELETE CASCADE ON UPDATE NO ACTION 
) 
; 
create trigger AppFile01_BI BEFORE INSERT 
on AppFile01  
referencing new as N 
for each row mode db2sql  
begin  
declare NxtSeq BIGINT ; 
set NxtSeq = NEXT VALUE FOR ID_SEQ ; 
insert into Master_IDENTITY values (NxtSeq) ; 
set N.sKeyAF = NxtSeq ; 
end  
; 
create table AppFile02 
(sKeyAF  BIGINT  not null  
, ts   timestamp default current timestamp 
, constraint AppFile02_PK  
    PRIMARY KEY (sKeyAF)  
, constraint AppFile02_FK  
    FOREIGN KEY (sKeyAF)  
    REFERENCES Master_IDENTITY (Master_ID) 
    ON DELETE CASCADE ON UPDATE NO ACTION 
) 
; 
create trigger AppFile02_BI BEFORE INSERT 
on AppFile02  
referencing new as N 
for each row mode db2sql 
begin  
declare NxtSeq BIGINT ; 
set NxtSeq = NEXT VALUE FOR ID_SEQ ; 
insert into Master_IDENTITY values (NxtSeq) ; 
set N.sKeyAF = NxtSeq ; 
end  
; 

而下面的請求,測試和顯示效果;沒有特別的原因,我選擇使用的文字值-1過,例如,DEFAULT

insert into AppFile01 values(-1, DEFAULT) ; 
; -- gets value 10000  
insert into AppFile02 values(-1, DEFAULT) 
     , (-1, DEFAULT) 
; -- gets values 10001 and 10002 
insert into AppFile01 values(-1, DEFAULT) ; 
; -- gets value 10003  
select * from master_id 
; -- likeness of report from above query 
      MASTER_ID 
      10,000 
      10,001 
      10,002 
      10,003 
select * from appfile01 
; -- likeness of report from above query 
      SKEYAF TS       
      10,000 2016-10-09-18.38.28.347468 
      10,003 2016-10-09-18.38.28.400702 
select * from appfile02 
; -- likeness of report from above query 
      SKEYAF TS       
      10,001 2016-10-09-18.38.28.372121 
      10,002 2016-10-09-18.38.28.386622 
+0

感謝@CRPence的解決方案!我希望這樣做沒有觸發器,但可能沒有其他選項... – JMX

+0

啊。我在鏈接主題中看到了這一點,但沒有提到這個主題,想避免觸發器。顯然,嘗試的方法是非觸發的:-),但似乎可能是死衚衕。 – CRPence