0

我有这个 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';

是否可以修改此函数以也采用列参数?如果有办法修改函数以获取列和表,则额外加分。

4

3 回答 3

3

作为一种替代方法,您可以通过使用带有 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 特定功能。

于 2011-11-18T15:33:06.250 回答
1

您想了解plsql 中的动态命令。只需构建您的查询并调用 EXECUTE。

于 2010-06-07T18:12:44.287 回答
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';
于 2011-05-18T09:44:15.647 回答