Båda problemen kräver att de (modifierade) JSON-elementen återskapas och aggregeras. För båda problemen skulle jag skapa en funktion för att göra det lättare att använda.
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 användas så här, t.ex. i en UPDATE-sats:
update the_table
set the_column = remove_element(the_column, '{"ModuleId": 1}')
where ...
För det andra problemet kommer en liknande funktion till hands.
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ören kommer att skriva över en befintlig nyckel, så detta ersätter effektivt det gamla namnet med det nya namnet.
Du kan använda det så här:
update the_table
set the_column = change_value(the_column, '{"ModuleId": 1}', '{"ModuleName": "CBA"}')
where ...;
Jag tror att det är lite mer flexibelt att skicka JSON-värdena än att hårdkoda nycklarna, vilket gör användningen av funktionen mycket begränsad. Den första funktionen kan också användas för att ta bort arrayelement genom att jämföra flera nycklar.
Om du inte vill skapa funktionerna, ersätt funktionsanropet med select
från funktionerna.