9

我有一张这样的桌子;

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->1data->3其他内容PL/*

4

2 回答 2

6

您不能直接操作json/jsonb类型的选定元素。Postgres 9.4 中仍然缺少此功能(请参阅@Craig 的评论)。您必须执行 3 个步骤:

  1. 取消嵌套/分解 JSON 值。
  2. 操作选定的元素。
  3. 再次聚合/组合值。

用第9.4页中的给定(新)值( )替换行中 json 数组data->3)的第三个元素:id = 1'<new_value>'

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

于 2014-12-09T13:33:05.010 回答
4

您可以使用jsonb_set从 PostgreSQL 9.5 执行此操作:

INSERT INTO test(data) VALUES('[1,2,"a",4,"8",6]');
UPDATE test SET data = jsonb_set(data, '{2}','"b"', false) WHERE id = 1

用一个简单的选择试试看:

SELECT jsonb_set('[1,2,"a",4,"8",6]', '{2}','"b"', false)
-- [1, 2, "b", 4, "8", 6]

如果你想更新两个字段,你可以这样做:

SELECT jsonb_set(jsonb_set('[1,2,"a",4,"8",6]', '{0}','100', false), '{2}','"b"', false)
-- [100, 2, "b", 4, "8", 6]
于 2020-01-18T20:24:42.310 回答