使用Postgres,如何使用UPDATE插入新的jsonb值如果为NULL或修改json如果已有值?

问题描述

我在Postgres(版本10)中有一个表,其中包含可为空的jsonb列:

CREATE TABLE j_play (
id                  serial PRIMARY KEY,created_ts          TIMESTAMPTZ,data                JSONB
); 

很可能记录最初可能没有json数据插入,因此该列将为空。

| id | created_ts                   | data
| 1  | 2020-09-11 18:18:37.47755+00 | [null]

我想更新此记录,以便如果“ null”添加了json对象,并且如果json对象已经存在,则对其进行修改

UPDATE j_play SET data = '{"a": "12345"}'
| id | created_ts                   | data
| 1  | 2020-09-11 18:18:37.47755+00 | {"a": "12345"}

UPDATE j_play SET data = '{"b": "54321"}'   -- This is obvIoUsly bogus but the intention is to amend existing json
| id | created_ts                   | data
| 1  | 2020-09-11 18:18:37.47755+00 | {"a": "12345","b": "54321"}

如果记录以一个空的json文档开头,那么我可以使用jsonb_set:

| id | created_ts                   | data
| 1  | 2020-09-11 18:18:37.47755+00 | {}
UPDATE j_play SET data = jsonb_set(rec_data,'{a}','"12345"',TRUE) WHERE id = 1

但是当初始值为NULL时,我不知道如何执行此操作。我可能可以将列初始化为{},但是我想知道是否存在一种从NULL更新它的优雅方法

解决方法

我想更新此记录,以便如果“ null”添加了json对象,并且如果json对象已经存在,则对其进行修改。

使用coalesce()

update j_play set data = coalesce(data,'{}') || '{"a": "12345"}';

Demo on DB Fiddle

insert into j_play (data) values(null);

update j_play set data = coalesce(data,'{}') || '{"a": "12345"}';
update j_play set data = coalesce(data,'{}') || '{"b": "54321"}';

select * from j_play;
id | created_ts | data                        
-: | :--------- | :---------------------------
 1 | null       | {"a": "12345","b": "54321"}