1 つのクエリで PostgreSQL シーケンスの nextval を複数回選択する簡潔な方法はありますか? 返される値はこれだけです。
たとえば、次のような本当に短くて甘いことをしたいと思います。
SELECT NEXTVAL('mytable_seq', 3) AS id;
そして得る:
id
-----
118
119
120
(3 rows)
1 つのクエリで PostgreSQL シーケンスの nextval を複数回選択する簡潔な方法はありますか? 返される値はこれだけです。
たとえば、次のような本当に短くて甘いことをしたいと思います。
SELECT NEXTVAL('mytable_seq', 3) AS id;
そして得る:
id
-----
118
119
120
(3 rows)
select nextval('mytable_seq') from generate_series(1,3);
generate_series は、引数で構成された連続番号を持つ多くの行を返す関数です。
上記の例では、各行の値は気にせず、generate_series を行ジェネレーターとして使用するだけです。そして、行ごとに nextval を呼び出すことができます。この場合、3 つの数値 (nextvals) を返します。
これを関数にラップすることはできますが、クエリがどれほど短いかを考えると、それが本当に賢明かどうかはわかりません。
この正確な問題については、「シーケンスから複数の値を取得する」という素晴らしい記事があります。
パフォーマンスが問題にならない場合 (たとえば、シーケンス値を使用すると値を取得するのに時間がかからない場合やnが小さい場合)、SELECT nextval('seq') FROM generate_series(1,n)アプローチが最も単純で最も適切です。
しかし、バルク ロード用のデータを準備する場合は、ロック内からシーケンスをnずつインクリメントするという記事の最後のアプローチが適切です。
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;
本当に 3 行を返す必要がない限り、選択ごとにシーケンスを 'INCREMENT BY 3' に設定します。次に、結果に 1 と 2 を単純に追加して、3 つのシーケンス番号を取得できます。
postgresql ドキュメントへのリンクを追加しようとしましたが、明らかにリンクを投稿することは許可されていません。
私の現在の最善の解決策は次のとおりです。
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呼び出しでも最小限のSQLが必要です。