9.17. Функции для работы с последовательностями
В этом разделе описаны функции для работы с объектами, представляющими последовательности. Такие объекты (также называемыми генераторами последовательностей или просто последовательностями) являются специальными таблицами из одной строки и создаются командой CREATE SEQUENCE. Используются они обычно для получения уникальных идентификаторов строк таблицы. Функции, перечисленные в Таблице 9.50, предоставляют простые и безопасные для параллельного использования методы получения очередных значений таких последовательностей.
Таблица 9.50. Функции для работы с последовательностями
Функция Описание |
|---|
Продвигает объект последовательности к следующему значению и возвращает это значение. Это действие атомарно: даже если вызвать Этой функции требуется право |
Устанавливает для объекта последовательности текущее значение и может также установить флаг SELECT setval('myseq', 42); При следующем вызове Результатом Этой функции требуется право |
Возвращает значение, выданное при последнем вызове Этой функции требуется право |
Возвращает значение, выданное при последнем вызове Этой функции требуется право |
Внимание
Во избежание блокирования параллельных транзакций, пытающихся получить значения одной последовательности, операция nextval никогда не откатывается; то есть, как только значение было выбрано, оно считается использованным и не будет возвращено снова. Это утверждение верно, даже когда окружающая транзакция впоследствии прерывается или вызывающий запрос никак не использует это значение. Например, команда INSERT с предложением ON CONFLICT вычислит кортеж, претендующий на добавление, произведя все требуемые вызовы nextval, прежде чем выявит конфликты, которые могут привести к отработке правил ON CONFLICT вместо добавления. В таких ситуациях в последовательности задействованных значений могут образовываться «дыры». Таким образом, объекты последовательностей Postgres Pro не годятся для получения непрерывных последовательностей.
В том же ключе любые изменения состояния последовательности, произведённые функцией setval, не отменяются при откате транзакции.
Последовательность, к которой будет обращаться одна из этих функций, определяется аргументом 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.19.
Примечание
В PostgreSQL до версии 8.1 аргументы этих функций имели тип text, а не regclass, и поэтому описанное выше преобразование текстовой строки в OID имело место при каждом вызове функции. Это поведение сохраняется и сейчас для обратной совместимости, но сейчас оно реализовано как неявное приведение типа text к типу regclass перед вызовом функции.
Когда вы записываете аргумент функции, работающей с последовательностью, как текстовую строку в чистом виде, она становится константой типа regclass. Так как фактически это будет просто значение OID, оно будет привязано к изначально идентифицированной последовательности, несмотря на то, что она может быть переименована, перенесена в другую схему и т. д. Такое «раннее связывание» обычно желательно для ссылок на последовательности в значениях столбцов по умолчанию и представлениях. Но иногда возникает необходимость в «позднем связывании», когда ссылки на последовательности распознаются в процессе выполнения. Чтобы получить такое поведение, нужно принудительно изменить тип константы с regclass на text:
nextval('foo'::text) foo распознаётся во время выполненияЗаметьте, что версии PostgreSQL до 8.1 поддерживали только позднее связывание, так что это может быть полезно и для совместимости со старыми приложениями.
Конечно же, аргументом таких функций может быть не только константа, но и выражение. Если это выражение текстового типа, неявное приведение типов повлечёт разрешение имени во время выполнения.