Выберите несколько идентификаторов из последовательности PostgreSQL - PullRequest
19 голосов
/ 22 мая 2009

Существует ли краткий способ выбора следующего значения для последовательности PostgreSQL несколько раз в одном запросе? Это будет единственное возвращаемое значение.

Например, я хотел бы сделать что-то очень короткое и сладкое, например:

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

И получите:

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

Ответы [ 5 ]

43 голосов
/ 22 мая 2009
select nextval('mytable_seq') from generate_series(1,3);

generate_series - это функция, которая возвращает множество строк с последовательными номерами, настроенными в соответствии с ее аргументами.

В приведенном выше примере нам не важно значение в каждой строке, мы просто используем generate_series в качестве генератора строк. И для каждого ряда мы можем вызвать nextval. В этом случае он возвращает 3 числа (nextvals).

Вы можете заключить это в функцию, но я не уверен, действительно ли это разумно, учитывая, насколько коротким является запрос.

12 голосов
/ 26 мая 2009

Об этой проблеме есть замечательная статья: " получение нескольких значений из последовательностей ".

Если производительность не является проблемой, например, при использовании значений последовательности карликов время, используемое для их получения, или n мало, тогда SELECT nextval ('seq') FROM generate_series ( 1, n) подход является самым простым и наиболее подходящим.

Но при подготовке данных для массовых загрузок уместен последний подход из статьи увеличения последовательности на n изнутри блокировки.

1 голос
/ 22 мая 2009

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 голосов
/ 24 мая 2009

Если вы действительно не хотите, чтобы три строки были возвращены, я установил бы последовательность 'INCREMENT BY 3' для каждого выбора. Затем вы можете просто добавить 1 и 2, чтобы в результате были три последовательных номера.

Я пытался добавить ссылку на документы postgresql, но, очевидно, мне не разрешено публиковать ссылки.

0 голосов
/ 22 мая 2009

Мое лучшее на данный момент решение:

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.

...