postgresql中的动态upsert

postgresql中的动态upsert,postgresql,dynamic,upsert,Postgresql,Dynamic,Upsert,我有一个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 e

我有一个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';
是否可以修改此函数以同时接受列参数?如果有办法修改函数以获取列和表,则可获得额外奖励。

您想了解的内容。 只需构建查询并调用EXECUTE。

您想了解的内容。
只需构建查询并调用EXECUTE。

可能是一种更简单的方法,只需少行;)


也许是一种更简单的方法,只是少了一行;)


作为一种替代方法,您可以在不使用函数的情况下执行upsert,方法是使用insert+update和where子句,使它们仅在正确的情况下成功。例如

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特定函数。

作为一种替代方法,您可以使用带有where子句的insert+update来执行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特定函数。

如果两个事务试图同时插入一行,这将不起作用。除非您使用可序列化事务。并且它不允许postgres优化该函数。如果两个事务试图同时插入一行,则此操作无效。除非您使用可序列化事务。并且它不允许postgres优化该功能。