不幸的是,
the only tables
您可以访问
ON CONFLICT DO
子句是当前行值(如表名或别名(如果有的话))和建议但失败的行(如
excluded
桌子)。
这个
SET
和
WHERE
条款
ON CONFLICT DO UPDATE
可以使用表的名称(或别名)访问现有行,并使用特殊
排除
桌子。
但就你的情况而言,你可以通过分解来以更复杂的方式重建你需要的东西
jsonb
让你的价值观得到体现。您可以使用JSONPath函数
keyvalue()
以JSONB数组的形式获取对象的键和值。
WITH updates AS (
SELECT UNNEST($1::TEXT[]) AS _key,
UNNEST($2::TEXT[]) AS field,
UNNEST($3::NUMERIC[]) AS value
)
INSERT INTO legacy_hash (_key, data)
SELECT _key, jsonb_build_object(field, value)
FROM updates
ON CONFLICT (_key)
DO UPDATE SET data = jsonb_set(
legacy_hash.data,
ARRAY[jsonb_path_query_first(excluded.data, '$.keyvalue()[0]')->>'key'],
to_jsonb(
COALESCE((legacy_hash.data->>(jsonb_path_query_first(excluded.data, '$.keyvalue()[0]')->>'key'::text))::NUMERIC, 0)
+ (jsonb_path_query_first(excluded.data, '$.keyvalue()[0]')->>'value')::NUMERIC
)
);
或者,只需使用
MERGE
WITH updates AS (
SELECT UNNEST($1::TEXT[]) AS _key,
UNNEST($2::TEXT[]) AS field,
UNNEST($3::NUMERIC[]) AS value
)
MERGE INTO legacy_hash AS lh
USING updates AS u
ON u._key = lh._key
WHEN NOT MATCHED THEN
INSERT (_key, data)
VALUES (u._key, jsonb_build_object(u.field, u.value))
WHEN MATCHED THEN
UPDATE SET
data = jsonb_set(
lh.data,
ARRAY[u.field],
to_jsonb(COALESCE((lh.data->>u.field)::NUMERIC, 0) + u.value)
)
;
db<>fiddle