Begge problemer kræver unnesting og aggregering af de (modificerede) JSON-elementer. Til begge problemer ville jeg oprette en funktion for at gøre det nemmere at bruge.
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;
Funktionen kan bruges sådan, f.eks. i en OPDATERING:
update the_table
set the_column = remove_element(the_column, '{"ModuleId": 1}')
where ...
For det andet problem er en lignende funktion nyttig.
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;
||
operatør vil overskrive en eksisterende nøgle, så dette erstatter effektivt det gamle navn med det nye navn.
Du kan bruge det sådan her:
update the_table
set the_column = change_value(the_column, '{"ModuleId": 1}', '{"ModuleName": "CBA"}')
where ...;
Jeg tror, at det er lidt mere fleksibelt at videregive JSON-værdierne end at indkode tasterne, hvilket gør brugen af funktionen meget begrænset. Den første funktion kunne også bruges til at fjerne array-elementer ved at sammenligne flere nøgler.
Hvis du ikke ønsker at oprette funktionerne, skal du erstatte funktionskaldet med select
fra funktionerne.