0

次のテスト コードを使用して新しい PostgreSQLアップサート構文をテストしようとしていますが、構文エラーが発生します。

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:から に切り替えまし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
                ^

また、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);
4

2 に答える 2

5

これはエラーの上位の Google の結果です。

ON CONFLICT DO UPDATE command cannot affect row a second time

重複した競合 VALUESが原因である可能性があることを追加します。

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

この場合、dimset to を使用して 2 つの値を挿入しようとし5ます。インデックスと同様dimに、クエリ自体で競合することはできません。

マイクロサービスを実装してリクエストを処理しているときにこのエラーが発生しました。一部のリクエストには重複したレコードがありました。

于 2016-09-04T10:13:05.027 に答える