Ambos os problemas exigem desaninhar e agregar de volta os elementos JSON (modificados). Para ambos os problemas, eu criaria uma função para facilitar o uso.
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;
A função pode ser usada assim, por exemplo. em uma instrução UPDATE:
update the_table
set the_column = remove_element(the_column, '{"ModuleId": 1}')
where ...
Para o segundo problema, uma função semelhante é útil.
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;
O
||
O operador substituirá uma chave existente, de modo que isso substitui efetivamente o nome antigo pelo novo nome. Você pode usar assim:
update the_table
set the_column = change_value(the_column, '{"ModuleId": 1}', '{"ModuleName": "CBA"}')
where ...;
Acho que passar os valores JSON é um pouco mais flexível do que codificar as chaves, o que torna o uso da função muito limitado. A primeira função também pode ser usada para remover elementos da matriz comparando várias chaves.
Se você não quiser criar as funções, substitua a chamada da função pelo
select
das funções.