如何在PostgreSQL中更新JSONB列,这只是一个值数组并且没有键

时间:2018-09-19 07:20:25

标签: postgresql jsonb postgresql-9.5

我需要更新一个称为“ verticals”的jsonb列,它所保存的值的数组类似于HOM,BFB等。该数组中没有键。

表格:Product(verticals jsonb, code int)

“垂直”列中存储的样本值是

[HOM,rst,NLF,WELSAK,HTL,TRV,EVCU,GRT]

我需要将代码“ = 1”的“垂直”列中的值“ HOM”更新为“ XXX”

我的预期输出是

[XXX,rst,NLF,WELSAK,HTL,TRV,EVCU,GRT]

2 个答案:

答案 0 :(得分:0)

您应使用jsonb_set(目标jsonb,路径文本[],new_value jsonb [,create_missing布尔值])和array_position()或array_replace(anyarray,anyelement,anyelement)

https://www.postgresql.org/docs/9.5/static/functions-json.html https://www.postgresql.org/docs/10/static/functions-array.html

答案 1 :(得分:0)

Because you chose to store your data in a de-normalized way, updating it is more complicated then it has to be.

You need to first unnest the array (essentially normalizing the data), replace the values, then aggregate them back and update the column:

update product p
  set verticals = t.verticals
from (
  select jsonb_agg(case when x.v = 'HOM' then 'XXX' else x.v end order by idx) as verticals
  from product p2, jsonb_array_elements_text(p2.verticals) with ordinality as x(v,idx)
  where code = 1
) t
where p.code = t.code;

This assumes that product.code is a primary (or unique) key!

Online example: http://rextester.com/KZQ65481


If the order of the array elements is not important, this gets easier:

update product
   set verticals = (verticals - 'HOM')||'["XXX"]'
where code = 1;

This removes the element 'HOM' from the array (regardless of the posisition) and then appends 'XXX' to the end of the array.