8

所以我想试试jsonbPostgreSQL。在我的表中,我有一个名为typeextras的列。jsonb

样本数据extras看起来像{"param1": 10, "param2": 15}

我想只使用 sql 语句修改 JSON。我想做这样的事情:

如果超过 12 param1,则通过将 10 添加到其值来更新extras字段。param2extras

我怎样才能写出这样的 SQL 语句?我知道我可以在应用程序层轻松地做到这一点,但我想在 SQL 层本身做到这一点,因为我可能要处理的行数会很大,我不想在 db-application- 上浪费时间db 往返

4

2 回答 2

11

这应该在 PostgreSQL 9.5 中完成:

create table t (extras jsonb);
insert into t values
    ('{"param1": 10, "param2": 15}'),
    ('{"param1": 10, "param2": 5}');

UPDATE t 
  SET extras = jsonb_set(extras, '{param1}', ((extras->>'param1')::real + 10)::text::jsonb) 
  WHERE (extras#>>'{param2}')::real > 12;

select * from t;
            extras            
------------------------------
 {"param1": 10, "param2": 5}
 {"param1": 20, "param2": 15}
(2 rows)
于 2016-01-11T12:12:04.387 回答
1

jsonb类型旨在存储整个文档。如果您更改文档的任何部分,则需要为该列分配一个新值。因为 Postgres 将旧版本保留一段时间,这是一项昂贵的操作。

jsonb考虑到这一点,下面是一个如何不更新列的示例:

create table t1 (doc jsonb);

insert into t1 values 
    ('{"param1": 10, "param2": 15}'),
    ('{"param1": 10, "param2": 5}');

update  t1
set     doc = ('{"param1": ' ||
        ((doc->'param1')::text::int + 10)::text ||
        ', "param2": ' ||
        (doc->'param2')::text ||
        '}')::jsonb
where   (doc->'param2')::text::int > 12;

select * from t1;

这打印:

            doc
------------------------------
 {"param1": 10, "param2": 5}
 {"param1": 20, "param2": 15}
(2 rows)
于 2015-05-06T14:13:17.103 回答