UPSERT测试代码中的语法错误

Ale*_*ber 0 postgresql insert upsert postgresql-json postgresql-9.5

我正在尝试使用以下测试代码来测试新的PostgreSQL upsert语法,但是出现语法错误:

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
                ^
Run Code Online (Sandbox Code Playgroud)

为什么上面的代码会失败?

此外,该test1表具有多个约束(非负值和唯一的主键)。如何仅解决唯一性约束?

更新2:我已从切换UPDATEINSERT(很抱歉犯了一个愚蠢的错误!),但仍在语法上苦苦挣扎:

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
                ^
Run Code Online (Sandbox Code Playgroud)

我还尝试将JSON行更改为:

SELECT obj FROM JSONB_ARRAY_ELEMENTS(in_json_array)
Run Code Online (Sandbox Code Playgroud)

但这也失败了...

这是我的测试代码,为您提供方便:

select upsert('[{"key1":1,"key2":2},{"key1":3,"key2":4}]'::jsonb);
select upsert('[{"key1":1,"key2":2},{"key1":1,"key2":4}]'::jsonb);
Run Code Online (Sandbox Code Playgroud)

Paw*_*zur 5

由于这是Google出现错误的最高结果:

ON CONFLICT DO UPDATE command cannot affect row a second time
Run Code Online (Sandbox Code Playgroud)

我将补充说,它可能是由重复的冲突VALUES引起的,例如

INSERT INTO distributors (did, dname)
VALUES 
    (5, 'Gizmo Transglobal'), 
    (5, 'Associated Computing, Inc')
ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们尝试插入两个dim设置为的值5。如同dim索引一样,它在查询本身中不能有冲突。

我在实现微服务和处理请求时遇到了此错误,其中一些请求具有重复的记录。