2011-12-19 10 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値。 grailsはシーケンスからid値を取得し、後でdbトリガへの実際の挿入時にシーケンスからのid値を再度取得し、grailsによって与えられたid値を上書きするため、偶数IDが生成されることがわかりました。

これはどうすればよいですか?私にとって最善の解決策は、アイデンティティ・キー生成戦略を持つmysqlのように動作するoracleです。誰も私と意見を共有することはできますか?


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 Randy :)

+0

最初に、シーケンス値の「ギャップ」が許容可能かどうかを判断することです。彼らは一意にとどまっている限り、彼らはうまくいくはずです。 2番目の方法は、すべての挿入時に余分なIDを取得するオーバーヘッドが問題であるかどうかを判断することです。 – Randy

答えて

4

場合によっては、new.idがnullかどうかをチェックする戦略を使用することがあります。

nullの場合は、シーケンスがnullでない場合はそのシーケンスを使用し、指定された値を使用します。

一意制約は実際のエラーを防ぎます。

+0

idがnullの場合にのみシーケンスを使用する場合は+1 –

+0

+1これは私が使用する解決策です。ありがとうございました。 – emstol

関連する問題