【发布时间】:2016-02-14 15:06:09
【问题描述】:
我正在尝试使用以下测试代码测试新的 PostgreSQL upsert syntax,但出现语法错误:
test=> CREATE TABLE test1 (
test(> key1 integer PRIMARY KEY check (key1 > 0),
test(> key2 integer check (key2 > 0)
test(> );
CREATE TABLE
test=> CREATE OR REPLACE FUNCTION upsert(IN in_json_array jsonb)
test-> RETURNS void AS
test-> $func$
test$> UPDATE test1 t SET
test$> t.key1 = (obj->>'key1')::int,
test$> t.key2 = (obj->>'key2')::int
test$> FROM JSONB_ARRAY_ELEMENTS(in_json_array) obj
test$> WHERE t.key1 = obj->'key1'
test$> ON CONFLICT DO UPDATE SET
test$> key1 = excluded.key1,
test$> key2 = excluded.key2;
test$>
test$> $func$ LANGUAGE sql;
ERROR: syntax error at or near "ON"
LINE 9: ON CONFLICT DO UPDATE SET
^
请问上面的代码为什么会失败?
另外,test1 表有几个约束(非负值和唯一主键)。如何解决唯一性约束?
更新 2:我已从 UPDATE 切换到 INSERT(抱歉犯了愚蠢的错误!),但仍在为语法苦苦挣扎:
test=> CREATE OR REPLACE FUNCTION upsert(IN in_json_array jsonb)
test-> RETURNS void AS
test-> $func$
test$> INSERT into test1 AS t (t.key1, t.key2)
test$> VALUES ((obj->>'key1')::int, (obj->>'key2')::int)
test$> FROM JSONB_ARRAY_ELEMENTS(in_json_array) obj
test$> WHERE t.key1 = obj->'key1'
test$> ON CONFLICT DO UPDATE SET
test$> t.key1 = excluded.key1,
test$> t.key2 = excluded.key2;
test$> $func$ LANGUAGE sql;
ERROR: syntax error at or near "FROM"
LINE 6: FROM JSONB_ARRAY_ELEMENTS(in_json_array) obj
^
我也尝试将 JSON 行更改为:
SELECT obj FROM JSONB_ARRAY_ELEMENTS(in_json_array)
但这也失败了......
为了您的方便,这是我的测试代码:
select upsert('[{"key1":1,"key2":2},{"key1":3,"key2":4}]'::jsonb);
select upsert('[{"key1":1,"key2":2},{"key1":1,"key2":4}]'::jsonb);
【问题讨论】:
-
language plpgsql需要begin ... end块。你可能想要language sql -
谢谢,但这没有帮助(
BEGIN / END和LANGUAGE SQL都没有) -
PostgreSQL 9.5.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16), 64-bit来自用于 CentOS 6.7 Linux 的postgresql95-server-9.5.1-1PGDG.rhel6.x86_64软件包。
标签: postgresql insert upsert postgresql-9.5 postgresql-json