Postgres Обновление нескольких ключей jsonb_set
У меня есть таблица DB с столбцом jsonb.
number | data
1 | {"name": "firstName", "city": "toronto", "province": "ON"}
Мне нужен способ обновить столбец данных.
Поэтому мой вывод должен выглядеть так:
{"name": "firstName", "city": "ottawa", "province": "ON", "phone": "phonenum", "prefix": "prefixedName"}
Возможно ли это с помощью json_set?
Я добавил запрос как:
update table_name set data = jsonb_set(data, '{city}', '"ottawa"') where number = 1;
Однако мне нужен способ добавить новое значение ключа, если оно не существует, и обновить значение ключа, если оно существует. Можно ли добиться этого в одном запросе?
Ответы
Ответ 1
Документация :
|| оператор конкатенирует элементы на верхнем уровне каждого из своих операндов.... Например, если оба операнда представляют собой объекты с общим именем поля ключа, значение поля в результате будет просто значением из правого операнда.
Итак, используя данные вашего примера:
update table_name set
data = data || '{"city": "ottawa", "phone": "phonenum", "prefix": "prefixedName"}'
where number = 1;
Кроме того, если объект, который вы хотите отредактировать, находится не на верхнем уровне - просто объедините функцию конкатенации и jsonb_set
. Например, если исходные данные выглядят как
{"location": {"name": "firstName", "city": "toronto", "province": "ON"}}
затем
...
data = jsonb_set(data, '{location}', data->'location' || '{"city": "ottawa", "phone": "phonenum", "prefix": "prefixedName"}')
...
Ответ 2
Вы можете попробовать это
Здесь мы используем оператор jsonb
concatation ||
для объединения двух jsonb-объектов
update table_name set data = (select val from (
(select
CASE WHEN data ? key THEN jsonb_set(data, '{' || key || '}', quote_nullable(updated_value))
ELSE
data || ('{' || quote_ident(key) || ':' || quote_ident(some_value) || '}')::jsonb
END val
from json_each_text((select data::json from tbl))
CROSS JOIN tbl t
where key in ('city','phone','prefix') and number=1)) where number=1