sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo modificar o eliminar un objeto JSON específico de la matriz JSON almacenada en el tipo de columna jsonb en PostgreSQL usando la cláusula where?

Ambos problemas requieren anidar y volver a agregar los elementos JSON (modificados). Para ambos problemas, crearía una función para que sea más fácil de usar.

create function remove_element(p_value jsonb, p_to_remove jsonb)
  returns jsonb
as
$$
  select jsonb_agg(t.element order by t.idx)  
  from jsonb_array_elements(p_value) with ordinality as t(element, idx)
  where not t.element @> p_to_remove;
$$
language sql
immutable;

La función se puede utilizar así, p. en una instrucción UPDATE:

update the_table
  set the_column = remove_element(the_column, '{"ModuleId": 1}')
where ...

Para el segundo problema, una función similar es útil.

create function change_value(p_value jsonb, p_what jsonb, p_new jsonb)
  returns jsonb
as
$$
  select jsonb_agg(
         case
           when t.element @> p_what then t.element||p_new
           else t.element
         end order by t.idx)  
  from jsonb_array_elements(p_value) with ordinality as t(element, idx);
$$
language sql
immutable;

El || el operador sobrescribirá una clave existente, por lo que efectivamente reemplaza el nombre antiguo con el nuevo nombre.

Puedes usarlo así:

update the_table
  set the_column = change_value(the_column, '{"ModuleId": 1}', '{"ModuleName": "CBA"}')
where ...;

Creo que pasar los valores JSON es un poco más flexible que codificar las claves, lo que hace que el uso de la función sea muy limitado. La primera función también podría usarse para eliminar elementos de la matriz comparando varias claves.

Si no desea crear las funciones, reemplace la llamada de función con select de las funciones.