Обновите определенные элементы массива json-массива в PostgreSQL 9.4

У меня есть такая таблица;

CREATE TABLE test (
  id BIGSERIAL PRIMARY KEY,
  data JSONB
);

INSERT INTO test(data) VALUES('[1,2,"a",4,"8",6]'); -- id = 1
INSERT INTO test(data) VALUES('[1,2,"b",4,"7",6]'); -- id = 2

Как заменить элемент data->1 и data->3 на что-то другое без PL/*?


person Kokizzu    schedule 04.12.2014    source источник


Ответы (2)


Вы не можете напрямую управлять выбранными элементами типа json / jsonb. Функциональность для этого все еще отсутствует в Postgres 9.4 (см. Комментарий @ Craig). Вам нужно сделать 3 шага:

  1. Разложите / разложите значение JSON.
  2. Управляйте выбранными элементами.
  3. Снова объедините / скомпонуйте значение.

Чтобы заменить 3-й элемент массива json (data->3) в строке на id = 1 с заданным (новым) значением ('<new_value>') в pg 9.4:

UPDATE test t
SET    data = t2.data
FROM  (
   SELECT id, array_to_json(
                 array_agg(CASE WHEN rn = 1 THEN '<new_value>' ELSE elem END))
              ) AS data
   FROM   test t2
        , json_array_elements_text(t2.data) WITH ORDINALITY x(elem, rn)         
   WHERE  id = 1
   GROUP  BY 1
   ) t2
WHERE  t.id = t2.id
AND    t.data <> t2.data; -- avoid empty updates

О json_array_elements_text():

О WITH ORDINALITY:

person Erwin Brandstetter    schedule 09.12.2014
comment
Функции для преобразования значений jsonb должны появиться в 9.5. Нет ничего принципиально отличного от любой другой функции, которая принимает входные данные и производит выходные данные. В основном, пока еще никто не реализовал функции по замене элементов и т. Д. - person Craig Ringer; 09.12.2014