Выберите несколько идентификаторов из последовательности PostgreSQL

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

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

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

И получить:

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

5 ответов

Решение
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 изнутри блокировки.

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

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


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;

Мое текущее лучшее решение:

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.

Другие вопросы по тегам