使用取消嵌套功能插入 - 跳过序列列中的数字

问题描述 投票:0回答:2

我正在尝试使用

unnest
中的
insert
功能。这样做时,序列号会为每个插入跳过一个数字。

mydb=# \d tab1  
                         Table "public.tab1"  
 Column |  Type   |                     Modifiers                         
--------+---------+---------------------------------------------------  
 id     | integer | not null default nextval('tab1_id_seq'::regclass)  
 col1   | integer |   
 col2   | integer |   
Indexes:  
    "tab1_pkey" PRIMARY KEY, btree (id)  
  
mydb=# insert into tab1(id,col1,col2) values (nextval('tab1_id_seq'),1,unnest(array[4,5]));  
INSERT 0 2  
mydb=# select * from tab1;  
 id | col1 | col2   
----+------+------  
  1 |    1 |    4  
  2 |    1 |    5  
(2 rows)  
  
mydb=# insert into tab1(id,col1,col2) values (nextval('tab1_id_seq'),2,unnest(array[4,5]));  
INSERT 0 2  
mydb=# select * from tab1;  
 id | col1 | col2   
----+------+------  
  1 |    1 |    4  
  2 |    1 |    5  
  4 |    2 |    4  
  5 |    2 |    5  
(4 rows)  
  
mydb=# insert into tab1(col1,col2) values(2,unnest(array[4,5]));  
INSERT 0 2  
mydb=# select * from tab1;  
 id | col1 | col2   
----+------+------  
  1 |    1 |    4  
  2 |    1 |    5  
  4 |    2 |    4  
  5 |    2 |    5  
  7 |    2 |    4  
  8 |    2 |    5  
(6 rows)  
  
mydb=# insert into tab1(col2) values(unnest(array[4,5]));  
INSERT 0 2  
mydb=# select * from tab1;  
 id | col1 | col2   
----+------+------  
  1 |    1 |    4  
  2 |    1 |    5  
  4 |    2 |    4  
  5 |    2 |    5  
  7 |    2 |    4  
  8 |    2 |    5  
 10 |      |    4  
 11 |      |    5  
(8 rows)  

mydb=# select nextval('tab1_id_seq');  
 nextval   
---------  
      13  
(1 row)  

对于每个

insert
,它都会跳过
id
列中的一个数字。

arrays function postgresql auto-increment
2个回答
11
投票

unnest
返回多行,因此在
VALUES
的单行中使用它有点麻烦。尽管它确实有效,但似乎
nextval
调用以某种方式被评估了两次。

您可以将插入编写为

INSERT INTO ... SELECT ...
而不是
INSERT INTO ... VALUES
:在 PostgreSQL 中,
VALUES
只是一个行构造函数。所以考虑写这样的东西:

insert into tab1(col1, col2) select 1, unnest(array[4,5])

2
投票

如果您在

insert ... select
的 from 子句中使用 unnest 函数,它不会跳过额外的 ID。

如:

insert into tab1(col1,col2)
select
   1, u.val
from
   unnest(array[4,5]) as u(val);

我认为通过将其放入值子句中,您将违反已弃用的 postgresql 特定扩展。 Postgresql 文档对此进行了说明:

目前,返回集合的函数也可以在select中调用 查询列表。对于查询自身生成的每一行, 调用返回 set 的函数,并生成一个输出行 函数结果集中的每个元素。但请注意,这 该功能已弃用,并可能在未来版本中删除。

© www.soinside.com 2019 - 2024. All rights reserved.