2009-05-22 59 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是合適的。