jsonb_set example postgresql

postgresql - example - postgres jsonb_set actualización de múltiples claves



jsonb_set example (2)

Tengo tabla de base de datos con la columna jsonb.

number | data 1 | {"name": "firstName", "city": "toronto", "province": "ON"}

Necesito una forma de actualizar la columna de datos. Así que mi salida debería ser como:

{"name": "firstName", "city": "ottawa", "province": "ON", "phone": "phonenum", "prefix": "prefixedName"}

¿Es posible con json_set? He añadido la consulta como:

update table_name set data = jsonb_set(data, ''{city}'', ''"ottawa"'') where number = 1;

Sin embargo, necesito una forma de agregar un nuevo valor clave si no existe y actualizar el valor clave si existe. ¿Es posible lograr esto en una sola consulta?


La documentación dice :

El || El operador concatena los elementos en el nivel superior de cada uno de sus operandos. ... Por ejemplo, si ambos operandos son objetos con un nombre de campo de clave común, el valor del campo en el resultado solo será el valor del operando de la derecha .

Así que usando sus datos de ejemplo:

update table_name set data = data || ''{"city": "ottawa", "phone": "phonenum", "prefix": "prefixedName"}'' where number = 1;

Además, si el objeto que desea editar no está en el nivel superior, simplemente combine la concatenación y la función jsonb_set . Por ejemplo, si los datos originales parecen

{"location": {"name": "firstName", "city": "toronto", "province": "ON"}}

entonces

... data = jsonb_set(data, ''{location}'', data->''location'' || ''{"city": "ottawa", "phone": "phonenum", "prefix": "prefixedName"}'') ...


Puedes probar esto

Aquí estamos utilizando el operador de jsonb jsonb || Concatenar dos objetos 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