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

How do I insert a value into a Postgres DB column array at a specific position?

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;

我不记得允许你自动换档的数组函数,所以这里有一些编码:

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 - 它的价值

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

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');