Постгреси змінюють послідовність вручну


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
Що означає останній аргумент "правда"?
inafalcao

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.
mariotomo

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
Erwin Brandstetter

1
@MitalPritmani: Можливо, вам потрібні типові касти. Розгляньте додані вище інструкції.
Ервін Брандстеттер

1
@NuclearPeon Я думаю, ти маєш на увазі SELECT setval('sequence', (SELECT MAX(col) from table), TRUE);інакше твої парени не вирівнюються .
длан

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
  • 2-й параметр - Далі nextval
  • 3-й параметр необов’язковий.

Використання true або false у третьому параметрі 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.