2010-06-07 60 views
0

我有這個upsert函數,允許我修改一行的fill_rate列。postgresql中的動態upsert

CREATE FUNCTION upsert_fillrate_alarming(integer, boolean) RETURNS VOID AS ' 
DECLARE 
    num ALIAS FOR $1; 
    dat ALIAS FOR $2; 

BEGIN 
    LOOP 
     -- First try to update. 
    UPDATE alarming SET fill_rate = dat WHERE equipid = num; 
    IF FOUND THEN 
     RETURN; 
    END IF; 
    -- Since its not there we try to insert the key 
    -- Notice if we had a concurent key insertion we would error 
    BEGIN 
     INSERT INTO alarming (equipid, fill_rate) VALUES (num, dat); 
     RETURN; 
    EXCEPTION WHEN unique_violation THEN 
     -- Loop and try the update again 
    END; 
    END LOOP; 
END; 
' LANGUAGE 'plpgsql'; 

是否有可能修改此函數以獲取列參數?如果有辦法修改函數以獲取列和表格,則需要額外的獎勵分數。

回答

0

也許更簡單的方法,只是少線;)

CREATE OR REPLACE FUNCTION upsert_tableName(arg1 type, arg2 type) RETURNS VOID AS $$ 
DECLARE 
BEGIN 
    UPDATE tableName SET col1 = value WHERE colX = arg1 and colY = arg2; 
    IF NOT FOUND THEN 
    INSERT INTO tableName values (value, arg1, arg2); 
    END IF; 
END; 
$$ LANGUAGE 'plpgsql'; 
3

作爲一種替代方法,您可以通過使用插入+更新WHERE子句,使他們只許成功做一個UPSERT 沒有功能在正確的情況下。例如。

update mytable set col1='value1' where (col2 = 'myId'); 
insert into mytable select 'value1', 'myId' where not exists (select 1 from mytable where col2='myId'); 

這將避免有大量的自定義postgres特定功能。

+1

如果兩個事務嘗試在同一時間插入一行,這將不起作用。除非你使用可序列化的事務。 – 2013-07-17 01:31:24

+0

,它不允許postgres針對該功能進行優化。 – baash05 2014-02-05 04:08:49