Beide problemen vereisen het verwijderen en aggregeren van de (aangepaste) JSON-elementen. Voor beide problemen zou ik een functie maken om dat gebruiksvriendelijker te maken.
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;
De functie kan als volgt worden gebruikt, b.v. in een UPDATE-verklaring:
update the_table
set the_column = remove_element(the_column, '{"ModuleId": 1}')
where ...
Voor het tweede probleem komt een soortgelijke functie van pas.
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;
De ||
operator zal een bestaande sleutel overschrijven, dus dit vervangt effectief de oude naam door de nieuwe naam.
Je kunt het als volgt gebruiken:
update the_table
set the_column = change_value(the_column, '{"ModuleId": 1}', '{"ModuleName": "CBA"}')
where ...;
Ik denk dat het doorgeven van de JSON-waarden een beetje flexibeler is dan het hardcoderen van de sleutels, waardoor het gebruik van de functie zeer beperkt is. De eerste functie kan ook worden gebruikt om array-elementen te verwijderen door meerdere sleutels te vergelijken.
Als u de functies niet wilt maken, vervangt u de functieaanroep door de select
van de functies.