Cả hai vấn đề đều yêu cầu hủy ghi chú và tổng hợp lại các phần tử JSON (đã sửa đổi). Đối với cả hai vấn đề, tôi sẽ tạo một hàm để làm cho nó dễ sử dụng hơn.
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;
Hàm có thể được sử dụng như thế này, ví dụ:trong một tuyên bố CẬP NHẬT:
update the_table
set the_column = remove_element(the_column, '{"ModuleId": 1}')
where ...
Đối với vấn đề thứ hai, một chức năng tương tự có ích.
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;
||
toán tử sẽ ghi đè lên một khóa hiện có, do đó, điều này có hiệu quả thay thế tên cũ bằng tên mới.
Bạn có thể sử dụng nó như thế này:
update the_table
set the_column = change_value(the_column, '{"ModuleId": 1}', '{"ModuleName": "CBA"}')
where ...;
Tôi nghĩ rằng việc chuyển các giá trị JSON linh hoạt hơn một chút sau đó mã hóa cứng các khóa khiến việc sử dụng hàm bị hạn chế rất nhiều. Hàm đầu tiên cũng có thể được sử dụng để xóa các phần tử mảng bằng cách so sánh nhiều khóa.
Nếu bạn không muốn tạo các hàm, hãy thay thế lệnh gọi hàm bằng select
từ các chức năng.