我正在尝试使用
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
列中的一个数字。
unnest
返回多行,因此在 VALUES
的单行中使用它有点麻烦。尽管它确实有效,但似乎 nextval
调用以某种方式被评估了两次。
您可以将插入编写为
INSERT INTO ... SELECT ...
而不是 INSERT INTO ... VALUES
:在 PostgreSQL 中,VALUES
只是一个行构造函数。所以考虑写这样的东西:
insert into tab1(col1, col2) select 1, unnest(array[4,5])
如果您在
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 的函数,并生成一个输出行 函数结果集中的每个元素。但请注意,这 该功能已弃用,并可能在未来版本中删除。