Le troisième argument de jsonb_set()
devrait être de jsonb
taper. Le problème est de convertir une chaîne de texte en chaîne jsonb, vous avez besoin d'une chaîne entre guillemets doubles. Vous pouvez utiliser concat()
ou format()
:
update animal
set info =
jsonb_set(info, '{location}', concat('"', lower(info->>'location'), '"')::jsonb, true)
-- jsonb_set(info, '{location}', format('"%s"', lower(info->>'location'))::jsonb, true)
where id='49493'
returning *;
id | info
-------+------------------------------------------------------------------
49493 | {"habit1": "fly", "habit2": "dive", "location": "sonoma narite"}
(1 row)
Dans Postgres 9.4 vous devez désimbriquer la colonne json à l'aide de jsonb_each_text(), agréger les clés et les valeurs en modifiant la valeur appropriée à la volée, et enfin créer un objet json :
update animal a
set info = u.info
from (
select id, json_object(
array_agg(key),
array_agg(
case key when 'location' then lower(value)
else value end))::jsonb as info
from animal,
lateral jsonb_each_text(info)
group by 1
) u
where u.id = a.id
and a.id = 49493;
Si vous pouvez créer des fonctions, cette solution pourrait être plus agréable :
create or replace function update_info(info jsonb)
returns jsonb language sql as $$
select json_object(
array_agg(key),
array_agg(
case key when 'location' then lower(value)
else value end))::jsonb
from jsonb_each_text(info)
$$
update animal
set info = update_info(info)
where id = 49493;