9.16. Функции для работы с последовательностями
В этом разделе описаны функции для работы с объектами, представляющими последовательности. Такие объекты (также называемыми генераторами последовательностей или просто последовательностями) являются специальными таблицами из одной строки и создаются командой CREATE SEQUENCE. Используются они обычно для получения уникальных идентификаторов строк таблицы. Функции, перечисленные в Таблице 9.44, предоставляют простые и безопасные для параллельного использования методы получения очередных значений таких последовательностей.
Таблица 9.44. Функции для работы с последовательностями
| Функция | Тип результата | Описание | 
|---|---|---|
|  | bigint | Выдаёт значение заданной последовательности, которое было возвращено при последнем вызове функции nextval | 
|  | bigint | Выдаёт значение любой последовательности, которое было возвращено при последнем вызове функции nextval | 
|  | bigint | Продвигает последовательность к следующему значению и возвращает его | 
|  | bigint | Устанавливает текущее значение последовательности | 
|  | bigint | Устанавливает текущее значение последовательности и флаг is_called, указывающий на то, что это значение использовалось | 
Последовательность, к которой будет обращаться одна из этих функций, определяется аргументом regclass, задающим просто OID последовательности в системном каталоге pg_class. Вычислять этот OID вручную не нужно, так как процедура ввода данных regclass автоматически выполнит эту работу за вас. Просто запишите имя последовательности в апострофах, чтобы оно выглядело как строковая константа. Для совместимости с обычными именами SQL эта строка будет переведена в нижний регистр, если только она не заключена в кавычки. Например: 
nextval('foo')      обращается к последовательности foo
nextval('FOO')      обращается к последовательности foo
nextval('"Foo"')    обращается к последовательности FooПри необходимости имя последовательности можно дополнить именем схемы:
nextval('myschema.foo')     обращается к myschema.foo
nextval('"myschema".foo')   то же самое
nextval('foo')              ищет foo в пути поиска Подробнее тип regclass описан в Разделе 8.18.
Примечание
В PostgreSQL до версии 8.1 аргументы этих функций имели тип text, а не regclass, и поэтому описанное выше преобразование текстовой строки в OID имело место при каждом вызове функции. Это поведение сохраняется и сейчас для обратной совместимости, но сейчас оно реализовано как неявное приведение типа text к типу regclass перед вызовом функции.
Когда вы записываете аргумент функции, работающей с последовательностью, как текстовую строку в чистом виде, она становится константой типа regclass. Так как фактически это будет просто значение OID, оно будет привязано к изначально идентифицированной последовательности, несмотря на то, что она может быть переименована, перенесена в другую схему и т. д. Такое «раннее связывание» обычно желательно для ссылок на последовательности в значениях столбцов по умолчанию и представлениях. Но иногда возникает необходимость в «позднем связывании», когда ссылки на последовательности распознаются в процессе выполнения. Чтобы получить такое поведение, нужно принудительно изменить тип константы с regclass на text: 
nextval('foo'::text)      foo распознаётся во время выполненияЗаметьте, что версии PostgreSQL до 8.1 поддерживали только позднее связывание, так что это может быть полезно и для совместимости со старыми приложениями.
Конечно же, аргументом таких функций может быть не только константа, но и выражение. Если это выражение текстового типа, неявное приведение типов повлечёт разрешение имени во время выполнения.
Ниже описаны все функции, предназначенные для работы с последовательностями:
- nextval
- Продвигает последовательность к следующему значению и возвращает его. Это атомарная операция: если - nextvalвызывается одновременно в нескольких сеансах, в результате каждого вызова будут гарантированно получены разные значения.- Если последовательность создаётся с параметрами по умолчанию, успешные вызовы - nextvalполучают очередные значения по возрастанию, начиная с 1. Другое поведение можно получить с помощью специальных параметров в команде CREATE SEQUENCE; подробнее это описано на странице описания команды.- Важно- Во избежание блокирования параллельных транзакций, пытающихся получить значения одной последовательности, операция - nextvalникогда не откатывается; то есть, как только значение было выбрано, оно считается использованным и не будет возвращено снова. Это утверждение верно, даже когда окружающая транзакция впоследствии прерывается или вызывающий запрос никак не использует это значение. Например, команда- INSERTс предложением- ON CONFLICTвычислит кортеж, претендующий на добавление, произведя все требуемые вызовы- nextval, прежде чем выявит конфликты, которые могут привести к отработке правил- ON CONFLICTвместо добавления. В таких ситуациях в последовательности задействованных значений могут образовываться «дыры». Таким образом, объекты последовательностей PostgreSQL не годятся для получения непрерывных последовательностей.
- currval
- Возвращает значение, выданное при последнем вызове - nextvalдля этой последовательности в текущем сеансе. (Если в данном сеансе- nextvalни разу не вызывалась для данной последовательности, возвращается ошибка.) Так как это значение ограничено рамками сеанса, эта функция выдаёт предсказуемый результат вне зависимости от того, вызвалась ли впоследствии- nextvalв других сеансах или нет.
- lastval
- Возвращает значение, выданное при последнем вызове - nextvalв текущем сеансе. Эта функция подобна- currval, но она не принимает в параметрах имя последовательности, а обращается к той последовательности, для которой вызывалась- nextvalв последний раз в текущем сеансе. Если в текущем сеансе функция- nextvalещё не вызывалась, при вызове- lastvalпроизойдёт ошибка.
- setval
- Сбрасывает счётчик последовательности. В форме с двумя параметрами устанавливает для последовательности заданное значение поля - last_valueи значение- trueдля флага- is_called, показывающего, что при следующем вызове- nextvalпоследовательность должна сначала продвинуться к очередному значению, которое будет возвращено. При этом- currvalтакже возвратит заданное значение. В форме с тремя параметрами флагу- is_calledможно присвоить- trueили- false. Со значением- trueона действует так же, как и форма с двумя параметрами. Если же присвоить этому флагу значение- false, первый вызов- nextvalпосле этого вернёт именно заданное значение, а продвижение последовательности произойдёт при последующем вызове- nextval. Кроме того, значение, возвращаемое- currvalв этом случае, не меняется. Например,- SELECT setval('foo', 42); Следующий вызов- nextvalвернёт 43 SELECT setval('foo', 42, true); То же самое SELECT setval('foo', 42, false); Следующий вызов- nextvalвернёт 42- Результатом самой функции - setvalбудет просто значение её второго аргумента.- Важно- Так как значения последовательностей изменяются вне транзакций, действие функции - setvalне отменяется при откате транзакции.