PostgreSQL вставить значение в каждый элемент массива JSONB
Есть следующий массив типа JSONB
[{"Price": 1494.0, "SkuId": 749802, "Quantity": 8},
{"Price": 4415.0, "SkuId": 2009534, "Quantity": 3},
{"Price": 4674.0, "SkuId": 1081083, "Quantity": 2}]
Необходимо в каждый элемент массива добавить OrderId. Должен работать следующий запрос
select
jsonb_insert('[{"Price": 1494.0, "SkuId": 749802, "Quantity": 8},
{"Price": 4415.0, "SkuId": 2009534, "Quantity": 3},
{"Price": 4674.0, "SkuId": 1081083, "Quantity": 2}]', CAST('{[0, 1], Order_Id}' as text[]), to_jsonb(3), true);
Однако, он выдаёт ошибку [22P02] ERROR: path element at position 1 is not an integer: "[*]"
Ответы (1 шт):
jsonb_insert обновляет только один элемент, т.к. json не гарантирует, что все элементы могут быть одинаковы, напр. [{"a"1}, 5, "ttt"]
Если нужно обновить только одну строку:
select jsonb_insert ('[{"Price": 1494.0, "SkuId": 749802, "Quantity": 8},
{"Price": 4415.0, "SkuId": 2009534, "Quantity": 3}]' :: jsonb,
'{0,OrderId}'::text[] , '0'::jsonb, false);
На выходе, у первого элемента добавится OrderId, а у последующих нет: [{"Price": 1494.0, "SkuId": 749802, "OrderId": 0, "Quantity": 8}, {"Price": 4415.0, "SkuId": 2009534, "Quantity": 3}]
Для обновления каждого элемента, можно разбить массив на отдельные элементы, и у каждого объекта json добавить нужное поле через оператор || , а затем объединить:
select jsonb_agg( t.j || '{"OrderId": 8}'::jsonb) from
(select jsonb_array_elements ('
[{"Price": 1494.0, "SkuId": 749802, "Quantity": 8},
{"Price": 4415.0, "SkuId": 2009534, "Quantity": 3},
{"Price": 4674.0, "SkuId": 1081083, "Quantity": 2}]' :: jsonb) as j ) t;