如何在特定位置的Postgres DB列数组中插入值?

时间:2017-10-23 12:12:15

标签: arrays insert postgresql-9.6

CREATE TABLE array_test (
  id serial primary key,
  data text[]
);

INSERT INTO array_test (data) VALUES
  ('{"one", "two"}');

- 现在我需要插入数组的第二个成员。我的尝试将如下,但代码只重新定义了第二个成员:

UPDATE array_test SET data[2] = 'three'
WHERE id = 1;

2 个答案:

答案 0 :(得分:1)

您可以切片现有数组并将新值附加到这些切片:

update array_test
   set data = data[:1]||'three'::text||data[2:];

data[:1]选择第一个元素之前的所有内容,data[2:]选择第二个元素之后的所有内容(包括)。

如果您经常需要这个,将它放入函数中可能是有意义的。

create or replace function array_set_at(p_data text[], p_pos int, p_element text)
  returns text[]
as
$$
  select p_data[:p_pos - 1]||p_element||p_data[p_pos:];
$$ 
language sql;

然后你可以这样做:

update array_test
   set data = array_set_at(data, 2, 'three');

答案 1 :(得分:0)

我不会重新调整允许你自动移位的数组函数,所以这里有一些编码:

t=# begin;
BEGIN
Time: 0.117 ms
t=#  with idx(v,t) as (values(2,'three'))
t-# , u as (select case when o > v then o+1 else o end, e from array_test,idx,unnest(data) with ordinality u(e,o) where id =1)
t-# , f as (select * from u union select * from idx)
t-# , r as (select array_agg(e order by o) from f)
t-# update array_test set data = array_agg
t-# from r
t-# where id =1;
UPDATE 1
Time: 0.635 ms
t=# select * from array_test;
 id |      data
----+-----------------
  1 | {one,two,three}
(1 row)

Time: 0.207 ms
t=# end;
COMMIT
Time: 0.874 ms

CTE idx(v,t) as (values(2,'three'))是您的[2]three - 值

相关问题