postgresql中的动态upsert

时间:2010-06-07 16:18:31

标签: postgresql dynamic upsert

我有这个upsert函数,允许我修改一行的fill_rate列。

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';

是否可以修改此函数以获取列参数?如果有办法修改函数以获取列和表,则额外奖励积分。

3 个答案:

答案 0 :(得分:3)

作为一种替代方法,您可以通过使用insert + update使用where + update来执行up而不用函数的upsert ,这使得它们只能在正确的情况下成功。 E.g。

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 :(得分:1)

您想了解dynamic commands in plsql。 只需构建您的查询并调用EXECUTE。

答案 2 :(得分: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';