PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come modificare o rimuovere un oggetto JSON specifico dall'array JSON archiviato nel tipo di colonna jsonb in PostgreSQL usando la clausola where?

Entrambi i problemi richiedono il disinnesto e l'aggregazione degli elementi JSON (modificati). Per entrambi i problemi creerei una funzione per renderla più facile da usare.

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 funzione può essere utilizzata in questo modo, ad es. in un'istruzione UPDATE:

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

Per il secondo problema torna utile una funzione simile.

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;

Il || l'operatore sovrascriverà una chiave esistente, quindi questo sostituisce efficacemente il vecchio nome con il nuovo nome.

Puoi usarlo in questo modo:

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

Penso che il passaggio dei valori JSON sia un po 'più flessibile rispetto all'hardcoding delle chiavi, il che rende l'uso della funzione molto limitato. La prima funzione potrebbe essere utilizzata anche per rimuovere elementi di array confrontando più chiavi.

Se non vuoi creare le funzioni, sostituisci la chiamata di funzione con select dalle funzioni.