И двата проблема изискват премахване и агрегиране обратно на (модифицираните) JSON елементи. И за двата проблема бих създал функция, която да я направи по-лесна за използване.
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;
Функцията може да се използва по този начин, напр. в оператор UPDATE:
update the_table
set the_column = remove_element(the_column, '{"ModuleId": 1}')
where ...
За втория проблем е полезна подобна функция.
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;
||
ще презапише съществуващ ключ, така че това ефективно заменя старото име с новото име.
Можете да го използвате по следния начин:
update the_table
set the_column = change_value(the_column, '{"ModuleId": 1}', '{"ModuleName": "CBA"}')
where ...;
Мисля, че предаването на JSON стойностите е малко по-гъвкаво от твърдото кодиране на ключовете, което прави използването на функцията много ограничено. Първата функция може също да се използва за премахване на елементи от масив чрез сравняване на множество ключове.
Ако не искате да създавате функциите, заменете извикването на функция с select
от функциите.