postgresql 中的动态 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';
是否可以修改此函数以也采用列参数?如果有办法修改函数以获取列和表,则会额外加分。
I have this upsert function that allows me to modify the fill_rate column of a row.
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';
Is it possible to modify this function to take a column argument as well? Extra bonus points if there is a way to modify the function to take a column and a table.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
作为一种替代方法,您可以在不使用函数的情况下执行 upsert,方法是使用带有 where 子句的插入 + 更新,使它们仅在正确的情况下成功。例如,
这将避免拥有大量自定义 postgres 特定功能。
As an alternative approach, you can do an upsert without a function by using an insert + update with where clauses to make them only succeed in the right case. E.g.
Which would avoid having lots of custom postgres specific functions.
您想阅读动态命令plsql。
只需构建您的查询并调用 EXECUTE。
You want to read about dynamic commands in plsql.
Just build your query and invoke EXECUTE.
也许有一个更简单的方法,只是更少的线;)
Maybe a simpler approach, just less line ;)