2011-04-11 67 views
1

引用比方說,我有一個項目表,併爲每個項目,也可以是存儲它的附加信息,這些信息將進入第二個表。附加信息由FK在第一個表中引用,可以爲NULL(如果該項沒有附加信息)。做UPSERT當行由FK

TABLE item (
    ... 
    item_addtl_info_id INTEGER 
) 

CONSTRAINT fk_item_addtl_info FOREIGN KEY (item_addtl_info) 
    REFERENCES addtl_info (addtl_info_id) 

TABLE addtl_info (
    addtl_info_id INTEGER NOT NULL 
    GENERATED BY DEFAULT 
    AS IDENTITY (
     INCREMENT BY 1 
     NO CACHE 
     ), 
    addtl_info_text VARCHAR(100) 
    ... 
    CONSTRAINT pk_addtl_info PRIMARY KEY (addtl_info_id) 
) 

什麼是「最佳實踐」來更新項目的附加信息(最好在IBM DB2 SQL中)?

它應該是一個UPSERT操作,這意味着如果附加信息尚不存在,則在第二個表中創建一個新記錄,但是如果它有,則只會更新,而第一個表中的FK會不變。

因此勢在必行,這是邏輯:

UPSERT(item, item_info): 
CASE WHEN item.item_addtl_info_id IS NULL THEN 
    INSERT INTO addtl_info (item_info) 
    UPDATE item.item_addtl_info_id (addtl_info.addtl_info_id) 
               ^^^^^^^^^^^^^ 
ELSE 
    UPDATE addtl_info (item_info) 
END 

我的主要問題是如何獲得新插入的addtl_info行的ID(以上的下劃線)。在一個存儲過程中,我可以從一個序列中請求該ID並將其存儲在一個變量中,但也許有一種更直接的方法。編程數據庫時不是總是出現這種情況嗎?

我的意思是,我真的不感興趣的只是addtl_info記錄的ID,只要它仍是唯一的,正確引用。所以在這種情況下使用序列對我來說似乎有點矯枉過正。

由於事實上,這UPSERT操作應該是SQL語言作爲標準操作的一部分(也許是的,我只是不知道呢?)......

回答

2

語法我一直在尋找的是:

SELECT * FROM NEW TABLE (INSERT INTO phone_book VALUES ('Peter Doe','555-2323')) 

維基百科(http://en.wikipedia.org/wiki/Insert_%28SQL%29

這是如何指向剛插入表中的記錄。

我的同事稱這種構建「就地觸發」,這到底是什麼......

這裏是我放在一起作爲一個複合SQL語句的第一個版本:

begin atomic 
declare addtl_id integer; 
set addtl_id = (select item_addtl_info_id from item where item.item_id = XXX); 
if addtl_id is null 
then 
    set addtl_id = (select addtl_info_id from new table 
        (insert into addtl_info 
         (addtl_info_text) 
         values ('My brand new additional info') 
        ) 
       ); 
    update item set item.item_addtl_info_id = addtl_id 
    where item.item_id = XXX; 

else 
    update addtl_info set addtl_info_text = 'My updated additional info' 
    where addtl_info.addtl_info_id = addtl_id; 
end if; 
end 

XXX等於項目ID被更新 - 此代碼可以容易地插入到一個存儲過程,以及XXX可以被轉換爲一個輸入參數。

我使用合併成也試過,但我無法找出語法用於更新從什麼是指定爲目標不同的表。