在这篇文章中,我尝试更新或删除JSONB
列的属性:
CREATE TABLE xxx (id BIGSERIAL, data JSONB);
INSERT INTO xxx(data) VALUES( '{"a":1,"b":2}' );
SELECT * FROM data;
id | data
----+------------------
1 | {"a": 1, "b": 2}
创建更新函数:
CREATE FUNCTION jsonb_merge(JSONB, JSONB)
RETURNS JSONB AS $$
WITH json_union AS (
SELECT * FROM JSONB_EACH($1)
UNION ALL
SELECT * FROM JSONB_EACH($2)
) SELECT JSON_OBJECT_AGG(key, value)::JSONB FROM json_union;
$$ LANGUAGE SQL;
测试:
-- replace
UPDATE xxx SET data = jsonb_merge(data,'{"b":3}') WHERE id = 1;
SELECT * FROM xxx;
id | data
----+------------------
1 | {"a": 1, "b": 3}
-- append
UPDATE xxx SET data = jsonb_merge(data,'{"c":4}') WHERE id = 1;
SELECT * FROM xxx;
id | data
----+-------------------------
1 | {"a": 1, "b": 3, "c": 4}
问题是:
JSONB_EACH
在这种情况下,使用(jsonb_merge) 而不是JSONB_EACH_TEXT
(来自文章)有什么缺点吗?jsonb_merge
如果第二个参数属性值是null
(类似于{"b":null}
)值将被删除,如何修改?
.
-- remove
UPDATE xxx SET data = jsonb_merge(data,'{"b":null}') WHERE id = 1;
SELECT * FROM xxx;
id | data
----+-----------------
1 | {"a": 1, "c": 4}
问题 1
应该没有明显的缺点。随着
value
转换回jsonb
无论如何,我猜想一直保持这种方式会更有效率。问题 2
只需将您的功能替换为以下内容(仅
WHERE key NOT IN ...
添加部分):