2009-05-22 58 views
16

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

例如,我愿做一些真正短暂的甜蜜,如:

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

并获得:

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

回答

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

generate_series是返回与序列号多行,通过它的参数配置的功能。

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

您可以将其封装到函数中,但我不确定在给定查询的时间短的情况下它是否真的合理。

+0

完全是我在找的,谢谢! – 2009-05-22 05:21:39

+3

请注意,3个麻烦(下一个)不保证是连续的。 – cquezel 2015-11-24 18:56:27

0

我目前最好的解决办法是:

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

哪将正确返回3行...但我希望即使多达100个或更多的NEXTVAL invo最小SQL的东西阳离子。

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; 
+0

请注意,由于使用'setof',您必须将此称为表格: `select * from foo(500);` – TML 2009-05-22 04:22:21

0

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

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

+0

赞赏,但在蚂蚁Aasma的链接中指出的垮台对我来说太陡,以致于无法改变增量......并且我需要的ids数量也各不相同,所以我更喜欢单独获取所有ID(这使得使用的代码无论如何,ids更简单)。 – 2009-05-28 02:29:18

11

有一篇关于这个确切问题的伟大文章:“getting multiple values from sequences”。

如果性能使用序列值时,是不是一个问题,比如矮人使用,让他们或ñ小的时候,那么SELECT NEXTVAL(“序列”)FROM generate_series(1,N)方法是最简单和最合适的。

但是,当准备批量加载数据时,最后一种方法是从锁内加密序列n是合适的。