Postgres вручную изменить последовательность


189

Я пытаюсь установить последовательность для определенного значения.

SELECT setval('payments_id_seq'), 21, true

Это дает ошибку:

ERROR: function setval(unknown) does not exist

Использование ALTER SEQUENCE, похоже, тоже не работает?

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Как это может быть сделано?

Ссылка: https://www.postgresql.org/docs/current/static/functions-sequence.html


4
Казалось бы, setval()есть как минимум два аргумента.

Ответы:


262

Скобки неуместны:

SELECT setval('payments_id_seq', 21, true);  # next value will be 22

В противном случае вы звоните setvalс одним аргументом, а для этого нужно два или три.


2
Что означает последний аргумент «истина»?
Инафалькао

15
trueозначает, что следующим значением будет предоставленное число + 1, в данном случае 22. falseозначает, что следующим значением будет предоставленное число, или 21. По умолчанию setval будет вести себя так, как если бы trueбыл выбран. Более подробная информация: postgresql.org/docs/9.6/static/functions-sequence.html
Том Мерц,

1
преимущество select setvalсинтаксиса в alter sequenceтом, что вы можете использовать вложенные запросы в нем, например, для select max(id) from payments.
Мариотомо

187

Этот синтаксис недопустим в любой версии PostgreSQL:

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Это будет работать:

ALTER SEQUENCE payments_id_seq RESTART WITH 22;

и эквивалентно:

SELECT setval('payments_id_seq', 22, FALSE);

Подробнее в текущем руководстве ALTER SEQUENCEи последовательности функций .

Обратите внимание, что setval()ожидает либо (regclass, bigint)или (regclass, bigint, boolean). В приведенном выше примере я предоставляю нетипизированные литералы . Это тоже работает. Но если вы передаете типизированные переменные в функцию, вам может потребоваться явное приведение типов, чтобы удовлетворить разрешению типа функции. Подобно:

SELECT setval(my_text_variable::regclass, my_other_variable::bigint, FALSE);

Для повторных операций вас могут заинтересовать:

ALTER SEQUENCE payments_id_seq START WITH 22; -- set default
ALTER SEQUENCE payments_id_seq RESTART;       -- without value

START [WITH]хранит номер по умолчанию RESTART, который используется для последующих RESTARTвызовов без значения. Для последней части вам нужен Postgres 8.4 или новее.


4
ALTER SEQUENCE [sequence] RESTART WITH (SELECT MAX(col) from table);не работает, а SELECT setval('sequence', (SELECT (MAX(col) from table), TRUE);работает. Я получаю синтаксическую ошибку. (Postgres 9.4)
NuclearPeon

1
Запрещен подзапрос в команде DDL («служебная команда»). См .: stackoverflow.com/a/36025963/939860
Эрвин Брандштеттер,

1
@MitalPritmani: Вам могут понадобиться приведения типов. Рассмотрим добавленные инструкции выше.
Эрвин Брандштеттер

1
@ NuclearPeon Я думаю, вы имеете в виду, SELECT setval('sequence', (SELECT MAX(col) from table), TRUE);иначе ваши парни не выстраиваются в очередь.
dland

1
@dland: В стороне: короче и быстрее эквивалент: SELECT setval('seq', max(col)) FROM tbl;См .: stackoverflow.com/a/23390399/939860
Эрвин Брандштеттер

33

использование select setval('payments_id_seq', 21, true);

setval содержит 3 параметра:

  • 1-й параметр sequence_name
  • Второй параметр следующий nextval
  • 3-й параметр не является обязательным.

Использование true или false в 3-м параметре setval выглядит следующим образом:

SELECT setval('payments_id_seq', 21);           // Next nextval will return 22
SELECT setval('payments_id_seq', 21, true);     // Same as above 
SELECT setval('payments_id_seq', 21, false);    // Next nextval will return 21

Лучший способ избежать жесткого кодирования имени последовательности, следующего значения последовательности и правильно обрабатывать пустую таблицу столбцов, можно использовать следующий способ:

SELECT setval(pg_get_serial_sequence('table_name', 'id'), coalesce(max(id), 0)+1 , false) FROM table_name;

где table_nameимя таблицы, idэто primary keyтаблицы


Спасибо! Последнее выражение именно то, что я искал. Это позволяет мне зарезервировать значения последовательности для последующего добавления партиями.
Тимур


0

Я не пытаюсь изменить последовательность с помощью setval. Но, используя ALTERменя, выдали, как правильно написать имя последовательности. И это работает только для меня:

  1. Проверьте требуемое имя последовательности, используя SELECT * FROM information_schema.sequences;

  2. ALTER SEQUENCE public."table_name_Id_seq" restart {number};

    В моем случае это было ALTER SEQUENCE public."Services_Id_seq" restart 8;

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.