26

是否有一种简洁的方法可以在 1 个查询中多次选择 PostgreSQL 序列的 nextval?这将是唯一返回的值。

例如,我想做一些非常简短和甜蜜的事情,比如:

SELECT NEXTVAL('mytable_seq', 3) AS id;

并得到:

 id  
-----
 118
 119
 120
(3 rows)
4

5 回答 5

58
select nextval('mytable_seq') from generate_series(1,3);

generate_series 是一个函数,它返回许多带有序列号的行,由它的参数配置。

在上面的例子中,我们不关心每一行的值,我们只是使用 generate_series 作为行生成器。对于每一行,我们都可以调用 nextval。在这种情况下,它返回 3 个数字(nextvals)。

您可以将其包装到函数中,但考虑到查询有多短,我不确定它是否真的很明智。

于 2009-05-22T05:09:22.103 回答
14

关于这个确切问题有一篇很棒的文章:“从序列中获取多个值”。

如果性能不是问题,例如当使用序列值使获取它们的时间相形见绌或n很小时,则SELECT nextval('seq') FROM generate_series(1,n)方法是最简单和最合适的。

但是在为批量加载准备数据时,文章中的最后一种方法是从锁中将序列增加n是合适的。

于 2009-05-25T20:33:09.020 回答
1

CREATE OR REPLACE FUNCTION foo() RETURNS SETOF INT AS $$
DECLARE
    seqval int; x int;
BEGIN
x := 0;

WHILE x < 100 LOOP
    SELECT into seqval nextval('f_id_seq');
    RETURN NEXT seqval;
    x := x+1;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql STRICT;

当然,如果您要做的只是推进序列,则可以使用 setval()

您还可以让函数获取循环次数的参数:

CREATE OR REPLACE FUNCTION foo(loopcnt int) RETURNS SETOF INT AS $$
DECLARE
    seqval int;       
    x int;
BEGIN
x := 0;
WHILE x < loopcnt LOOP
    SELECT into seqval nextval('f_id_seq');
    RETURN NEXT seqval;x := x+1;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql STRICT;
于 2009-05-22T04:16:28.027 回答
1

除非您真的想要返回三行,否则我会将每个选择的序列设置为“INCREMENT BY 3”。然后你可以简单地将 1 和 2 添加到结果中,得到你的三个序列号。

我试图添加一个指向 postgresql 文档的链接,但显然我不允许发布链接。

于 2009-05-23T21:16:08.847 回答
0

我目前最好的解决方案是:

SELECT NEXTVAL('mytable_seq') AS id
UNION ALL
SELECT NEXTVAL('mytable_seq') AS id
UNION ALL
SELECT NEXTVAL('mytable_seq') AS id;

这将正确返回 3 行......但我想要一些最小的 SQL,即使是 100 或更多的 NEXTVAL 调用。

于 2009-05-22T03:49:16.463 回答