Выберите несколько идентификаторов из последовательности 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.