Oba problémy vyžadují zrušení vnoření a zpětné agregování (upravených) prvků JSON. Pro oba problémy bych vytvořil funkci, která by to zjednodušila.
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;
Funkci lze takto použít např. v příkazu UPDATE:
update the_table
set the_column = remove_element(the_column, '{"ModuleId": 1}')
where ...
Pro druhý problém přijde vhod podobná funkce.
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;
||
operátor přepíše existující klíč, takže to efektivně nahradí starý název novým názvem.
Můžete jej použít takto:
update the_table
set the_column = change_value(the_column, '{"ModuleId": 1}', '{"ModuleName": "CBA"}')
where ...;
Myslím, že předávání hodnot JSON je o něco flexibilnější než pevné kódování klíčů, díky čemuž je použití funkce velmi omezené. První funkci lze také použít k odstranění prvků pole porovnáním více klíčů.
Pokud nechcete vytvářet funkce, nahraďte volání funkce select
z funkcí.