给一张table
CREATE TABLE balances
(
username varchar(255) NOT NULL,
currency varchar(255) NOT NULL,
balance numeric NULL,
CONSTRAINT balances_pkey PRIMARY KEY (username, currency)
);
尝试之后
CREATE OR REPLACE FUNCTION merge_balance(username varchar(255), currency varchar(255), to_add numeric) RETURNS void
AS $$ BEGIN
INSERT INTO balances(username, currency, to_add)
ON CONFLICT balances_pkey DO UPDATE SET balance = OLD.balance + to_add
END; $$ LANGUAGE plpgsql;
我明白了
ERROR: syntax error at or near "ON"
我的postgresql版本(在容器中运行)postgres:11.5)
SELECT version();
version
----------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 11.5 (Debian 11.5-3.pgdg90+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit
(1 row)
那些 ;
, $
事情太烦人了,现在我明白了=_=
有人解决过这样的问题吗?谢谢!
3条答案
按热度按时间w7t8yxp51#
不能在尝试时使用“old”。您所做的是引用dml语句为触发器生成的伪行old。即使可以引用,它也将为null,因为插入时所有旧列都为null。这不是你想要的结果将是空的。但是您确实需要为表设置别名,以避免update子句的歧义。此外,也不必在函数头上指定限制。尝试:
请参阅此处的完整示例。
事后我想您可以使用old.balance,使用old作为表别名。
但至少在我看来,这不是个好主意。,
kd3sttzy2#
考虑:
理论基础:
你需要一个
VALUES()
列出要插入的值的子句;将目标列环绕在列表中也是一种好的做法—为此,最好不要使用与表列同名的函数参数冲突目标必须用括号括起来-可以使用约束名称,但我发现使用列名更清楚
8cdiaqws3#
不应该吗