2011-12-19 29 views
1

我在grails中寫了一個webapp,並且第一次在oracle下面寫了。每個表已經從序列生成的ID和我的插入之前,使用觸發設置ID,如下所示:將它總是具有一個域對象期間即使是id值。整蠱序列映射(grails oracle)

CREATE TABLE "RECIPE" 
    ( "ID" NUMBER(19,0) NOT NULL ENABLE, 
    ... 
    PRIMARY KEY ("ID") ENABLE 
    ) 
/

CREATE SEQUENCE "RECIPE_SEQ" MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE 
/

CREATE OR REPLACE TRIGGER "BI_RECIPE" 
    before insert on "RECIPE"    
    for each row 
begin 
    select "RECIPE_SEQ".nextval into :NEW.ID from dual; 
end; 
/

我也發映射

static mapping = { 
     table 'RECIPE' 
     version false   
     id column:'ID', generator:'sequence', params:[sequence:'RECIPE_SEQ'] 
     ... 
} 

而現在甚至id值。我發現偶數ids是由於grails從序列中獲得一個id值而產生的,後來在實際插入到db觸發器的過程中,再次從序列中獲得一個id值並覆蓋了grails給出的值。

該怎麼辦?對我來說,最好的解決方案是使用身份密鑰生成策略的MySQL像MySQL一樣工作。有人可以與我分享一些意見嗎?


EDIT(解決方案):根據蘭迪的回答更是讓人在觸發添加條件如下圖所示:

CREATE OR REPLACE TRIGGER "BI_RECIPE" 
    before insert on "RECIPE"    
    for each row 
begin 
    if :NEW.ID IS NULL then 
     select "RECIPE_SEQ".nextval into :NEW.ID from dual; 
    end if; 
end; 
/

工作正常。 Thx蘭迪:)

+0

首先要確定序列值中的'間隙'是否可以容忍。只要它們保持獨特性,它們應該沒問題。第二它確定是否每個插入獲得額外的ID的開銷是一個問題 - 我懷疑它會。 – Randy 2011-12-19 14:24:02

回答

4

有時你可能會使用檢查策略:new.id是否爲空。

如果它爲空,則使用該序列,如果它不爲空,則使用提供的值。

唯一性約束將防止實際的錯誤。

+0

+1僅在id爲空時使用序列 – 2011-12-19 14:33:35

+0

+1這是我將使用的解決方案。謝謝。 – emstol 2011-12-20 08:45:26