我有这个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';
是否可以修改此函数以获取列参数?如果有办法修改函数以获取列和表,则额外奖励积分。
答案 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';