DECLARE
Эта страница переведена при помощи нейросети GigaChat.
DECLARE
- создание курсора.
Синтаксис
DECLARE name [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ]
CURSOR [ { WITH | WITHOUT } HOLD ] FOR query
Описание
DECLARE
позволяет пользователю создать курсор, с помощью которого можно извлекать небольшое количество строк из большого набора результатов запроса. После создания курсора строки из него извлекаются с помощью команды FETCH.
Эта страница описывает использование курсоров на уровне SQL-команд. Если курсоры используются внутри функции на PL/pgSQL, применяются другие правила — смотрите раздел «Курсор».
Параметры
name
- Имя создаваемого курсора. Оно должно отличаться от имени любого другого активного курсора в сеансе.
BINARY
- Возврат данных в двоичном формате, а не в текстовом.
ASENSITIVE
INSENSITIVE
- Чувствительность курсора определяет, будут ли видны изменения данных, сделанные в той же транзакции после объявления курсора.
INSENSITIVE
- изменения не видны;ASENSITIVE
- поведение зависит от реализации.
В PostgreSQL все курсоры являются нечувствительными, поэтому указание этих ключевых слов не оказывает эффекта и поддерживается лишь для совместимости со стандартом SQL.
Указание
INSENSITIVE
вместе сFOR UPDATE
илиFOR SHARE
приведет к ошибке.
SCROLL
NO SCROLL
SCROLL
- курсор может использоваться для получения строк в произвольном порядке, включая обратное направление.NO SCROLL
: курсор не может использоваться для произвольного доступа — только по порядку вперед. Значение по умолчанию допускает прокрутку в некоторых случаях, но не эквивалентно явномуSCROLL
. Смотрите «Примечания» ниже для получения подробной информации.
WITH HOLD
WITHOUT HOLD
WITH HOLD
указывает, что курсор может использоваться после завершения транзакции, в которой он был создан.WITHOUT HOLD
указывает, что курсор не может использоваться за пределами текущей транзакции (по умолчанию).
Ключевые слова ASENSITIVE
, BINARY
, INSENSITIVE
и SCROLL
могут появляться в любом порядке.
Примечания
Обычные курсоры возвращают данные в текстовом формате, как обычный SELECT
. Параметр BINARY
указывает возвращать данные в бинарном формате, что снижает затраты на преобразование, но требует дополнительной обработки на стороне клиента. Например, целое число 1 может быть возвращено как строка "1"
в текстовом режиме или как 4-байтовое значение во внутреннем представлении (в формате big-endian) в бинарном.
Многие приложения (включая psql
) не поддерживают бинарные курсоры и ожидают данные только в текстовом формате.
Когда клиентское приложение использует протокол «расширенный запрос» для выдачи команды FETCH
, сообщение протокола привязки указывает, должны ли данные извлекаться в текстовом или двоичном формате. Этот выбор заменяет способ определения курсора. Таким образом, концепция бинарного курсора как таковая устарела при использовании расширенного протокола запросов - любой курсор может рассматриваться как текстовый или бинарный.
Если не указано WITH HOLD
, курсор, созданный этой командой, может использоваться только в рамках текущей транзакции. Таким образом, DECLARE
без WITH HOLD
бесполезен вне блока транзакций: курсор будет существовать только до завершения оператора. Поэтому PostgreSQL сообщает об ошибке, если такая команда используется вне блока транзакций. Используйте BEGIN и COMMIT (или ROLLBACK) для определения блока транзакций.
Если указан WITH HOLD
и транзакция, которая создала курсор, успешно зафиксирована, курсор можно продолжать использовать в последующих транзакциях в одном сеансе. Но если создающая транзакция прерывается, курсор удаляется. Курсор, созданный с помощью WITH HOLD
, закрывается при явной команде CLOSE
, выданной на него, или когда заканчивается сеанс. В текущей реализации строки, представленные удерживаемым курсором, копируются во временный файл или область памяти, чтобы они оставались доступными для последующих транзакций.
WITH HOLD
не может быть указано при включении запроса FOR UPDATE
или FOR SHARE
.
Параметр SCROLL
следует указывать, если курсор предполагается использовать для обратного извлечения строк. Это требуется стандартом SQL. Но, для совместимости с более ранними версиями, PostgreSQL позволит обратные выборки без SCROLL
, если план запроса курсора достаточно прост, чтобы не требовалось дополнительных накладных расходов для его поддержки. Тем не менее, разработчикам приложений рекомендуется не полагаться на использование обратных выборок из курсора, который не был создан с использованием SCROLL
. Если указано NO SCROLL
, то обратные выборки запрещены в любом случае.
Обратные выборки также запрещены, когда запрос включает FOR UPDATE
или FOR SHARE
, поэтому SCROLL
не может быть указано в этом случае.
Прокручиваемые курсоры могут давать неожиданный результат, если они вызывают любые изменчивые функции (см. раздел «Категории волатильности функций»). Когда ранее извлеченная строка извлекается повторно, функции могут быть выполнены заново, возможно, приводя к результатам, отличным от первых. Лучше всего указать для запроса, включающего изменчивые функции. Если это нецелесообразно, одним из обходных путей является объявление курсора и фиксация транзакции перед чтением каких-либо строк из него. Это заставит весь вывод курсора материализоваться во временном хранилище, так что изменчивые функции будут выполняться точно один раз для каждой строки.
Если запрос курсора содержит FOR UPDATE
или FOR SHARE
, строки блокируются при первой выборке, как при обычном SELECT ... FOR UPDATE
, и возвращаются самые актуальные данные.
В общем случае рекомендуется использовать FOR UPDATE
если курсор предназначен для использования с UPDATE ... WHERE CURRENT OF
или DELETE ... WHERE CURRENT OF
. Использование FOR UPDATE
предотвращает изменение строк другими сессиями между временем их выборки и временем обновления. Без FOR UPDATE
, последующая команда WHERE CURRENT OF
не будет иметь никакого эффекта, если строка была изменена после создания курсора.
Еще одна причина использовать FOR UPDATE
заключается в том, что без него последующий WHERE CURRENT OF
может завершиться неудачей, если запрос курсора не соответствует правилам SQL-стандарта для «просто обновляемого» (в частности, курсор должен ссылаться только на одну таблицу и не использовать группировку или ORDER BY
). Курсор, который не является просто обновляемым, может работать, а может и нет, в зависимости от деталей выбора плана; поэтому в худшем случае приложение может работать при тестировании, а затем выйти из строя в производстве. Если указано FOR UPDATE
, то гарантируется, что курсор будет обновляемым.
Основная причина не использовать FOR UPDATE
с WHERE CURRENT OF
заключается в том, что нужен прокручиваемый курсор или изолированный от одновременных обновлений (т.е. продолжать показывать старые данные). Если это требование, внимательно следите за приведенными выше предостережениями.
Стандарт SQL предусматривает использование курсоров только во встроенном SQL. Сервер PostgreSQL не реализует оператор для курсоров, считается, что курсор открыт при его объявлении. Однако ECPG, препроцессор встроенного SQL для PostgreSQL, поддерживает стандартные соглашения SQL для курсоров, включая те, которые связаны с операторами DECLARE
и OPEN
.
Структура данных сервера, лежащая в основе открытого курсора, называется порталом. Имена порталов раскрываются в клиентском протоколе: клиент может напрямую извлекать строки из открытого портала, если знает имя портала. Когда создается курсор с помощью оператора DECLARE
, имя портала совпадает с именем курсора.
Для просмотра всех активных курсоров текущей сессии можно использовать системное представление pg_cursors.
Примеры
Для объявления курсора:
DECLARE liahona CURSOR FOR SELECT * FROM films;
Смотрите FETCH для дополнительных примеров использования курсора.
Совместимость
Стандарт SQL допускает курсоры только во встроенном SQL и модулях. PostgreSQL позволяет использовать курсоры интерактивно.
Согласно стандарту SQL, изменения, внесенные в нечувствительные курсоры с помощью операторов UPDATE ... WHERE CURRENT OF
и DELETE ... WHERE CURRENT OF
, видны в том же самом курсоре. PostgreSQL рассматривает эти операторы так же, как и все остальные операторы изменения данных, то есть они не видны в нечувствительных курсорах.
Бинарные курсоры являются расширением PostgreSQL.