DECLARE#

DECLARE

DECLARE

DECLARE — определить курсор

Синтаксис

DECLARE name [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ]
    CURSOR [ { WITH | WITHOUT } HOLD ] FOR query

Описание

DECLARE позволяет пользователю создавать курсоры, которые могут использоваться для извлечения небольшого количества строк за раз из большого запроса. После создания курсора строки извлекаются из него с помощью FETCH.

Примечание

Эта страница описывает использование курсоров на уровне команд SQL. Если вы пытаетесь использовать курсоры внутри функции PL/pgSQL, правила отличаются — см. Раздел 41.7.

Параметры

name

Имя создаваемого курсора.

BINARY

Заставляет курсор возвращать данные в двоичном формате, а не в текстовом формате.

ASENSITIVE
INSENSITIVE

Чувствительность курсора определяет, видны ли изменения в данных, лежащих в основе курсора, сделанные в той же транзакции после объявления курсора. INSENSITIVE означает, что они не видны, ASENSITIVE означает, что поведение зависит от реализации. Третье поведение, SENSITIVE, означающее, что такие изменения видны в курсоре, не доступно в Tantor SE. В Tantor SE все курсоры нечувствительны, поэтому эти ключевые слова не имеют эффекта и принимаются только для совместимости со стандартом SQL.

Спецификация INSENSITIVE вместе с FOR UPDATE или FOR SHARE является ошибкой.

SCROLL
NO SCROLL

SCROLL указывает, что курсор может использоваться для извлечения строк в не последовательном порядке (например, назад). В зависимости от сложности плана выполнения запроса, указание SCROLL может повлечь штраф к производительности времени выполнения запроса. NO SCROLL указывает, что курсор не может использоваться для извлечения строк в не последовательном порядке. По умолчанию разрешено прокручивание в некоторых случаях; это не то же самое, что указание SCROLL. См. раздел Notes ниже для получения подробной информации.

WITH HOLD
WITHOUT HOLD

WITH HOLD указывает, что курсор может продолжать использоваться после успешного завершения транзакции, создавшей его. WITHOUT HOLD указывает, что курсор не может использоваться за пределами транзакции, создавшей его. Если не указано ни WITHOUT HOLD, ни WITH HOLD, по умолчанию используется WITHOUT HOLD.

query

Команда SELECT или VALUES, которая предоставит строки, которые будут возвращены курсором.

Ключевые слова ASENSITIVE, BINARY, INSENSITIVE и SCROLL могут появляться в любом порядке.

Примечания

Все обычные курсоры возвращают данные в текстовом формате, так же, как и SELECT. Опция BINARY указывает, что курсор должен возвращать данные в бинарном формате. Это уменьшает усилия по преобразованию как на сервере, так и на клиенте, но требует больше усилий программиста для работы с платформозависимыми бинарными форматами данных. Например, если запрос возвращает значение "1" из столбца с целочисленными данными, то с обычным курсором вы получите строку 1, а с бинарным курсором вы получите 4-байтовое поле, содержащее внутреннее представление значения (в порядке байтов big-endian).

Бинарные курсоры следует использовать осторожно. Многие приложения, включая psql, не готовы обрабатывать бинарные курсоры и ожидают, что данные будут возвращаться в текстовом формате.

Примечание

Когда клиентское приложение использует протокол расширенного запроса для выполнения команды FETCH, сообщение протокола Bind определяет, будет ли извлекаться данные в текстовом или двоичном формате. Этот выбор переопределяет способ определения курсора. Понятие двоичного курсора как такового устарело при использовании протокола расширенного запроса — любой курсор может быть обработан как текстовый или двоичный.

Если не указано WITH HOLD, курсор, созданный этой командой, может использоваться только в пределах текущей транзакции. Таким образом, DECLARE без WITH HOLD бесполезен вне блока транзакции: курсор будет существовать только до завершения оператора. Поэтому Tantor SE сообщает об ошибке, если такая команда используется вне блока транзакции. Используйте BEGIN и COMMIT (или ROLLBACK) для определения блока транзакции.

Если указано WITH HOLD и транзакция, которая создала курсор, успешно коммитится, курсор может продолжать использоваться последующими транзакциями в той же сессии. (Но если создающая транзакция отменяется, курсор удаляется). Курсор, созданный с использованием WITH HOLD, закрывается при явном выполнении команды CLOSE или при завершении сессии. В текущей реализации строки, представленные удерживаемым курсором, копируются во временный файл или область памяти, чтобы они оставались доступными для последующих транзакций.

WITH HOLD не может быть указано, когда запрос включает FOR UPDATE или FOR SHARE.

Опция SCROLL должна быть указана при определении курсора, который будет использоваться для получения данных в обратном порядке. Это требуется стандартом SQL. Однако, для обеспечения совместимости с предыдущими версиями, Tantor SE позволяет выполнять обратные выборки без указания SCROLL, если план запроса курсора достаточно простой и не требует дополнительных затрат для его поддержки. Однако, разработчикам приложений рекомендуется не полагаться на использование обратных выборок из курсора, который не был создан с использованием SCROLL. Если указана опция NO SCROLL, то обратные выборки запрещены в любом случае.

В случае, когда запрос содержит FOR UPDATE или FOR SHARE, также запрещены обратные выборки; поэтому в этом случае нельзя указывать SCROLL.

Предостережение

Прокручиваемые курсоры могут давать неожиданные результаты, если они вызывают какие-либо изменчивые функции (см. Раздел 36.7). При повторном получении ранее выбранной строки функции могут быть повторно выполнены, что может привести к результатам, отличным от первого раза. Лучше всего указать NO SCROLL для запроса, включающего изменчивые функции. Если это не практично, одним из способов обхода является объявление курсора SCROLL WITH HOLD и коммит транзакции перед чтением строк из него. Это приведет к тому, что весь вывод курсора будет материализован во временном хранилище, так что изменчивые функции будут выполнены ровно один раз для каждой строки.

Если запрос курсора включает теги FOR UPDATE или FOR SHARE, то возвращаемые строки блокируются в момент первого получения, так же, как и для обычной команды SELECT с этими опциями. Кроме того, возвращаемые строки будут самыми актуальными версиями.

Предостережение

Считается хорошей практикой использовать тег 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. Сервер Tantor SEне реализует оператор OPEN для курсоров; курсор считается открытым при его объявлении. Однако ECPG, встроенный SQL-препроцессор для Tantor SE, поддерживает стандартные соглашения SQL по курсорам, включая операторы DECLARE и OPEN.

Вы можете увидеть все доступные курсоры, выполнив запрос к системному представлению pg_cursors.

Примеры

Для объявления курсора:

DECLARE liahona CURSOR FOR SELECT * FROM films;

См. FETCH для получения дополнительных примеров использования курсоров.

Совместимость

Стандарт SQL позволяет использовать курсоры только во встроенном SQL и в модулях. Tantor SE позволяет использовать курсоры в интерактивном режиме.

Согласно стандарту SQL, изменения, внесенные в нерегистрозависимые курсоры с помощью операторов UPDATE ... WHERE CURRENT OF и DELETE ... WHERE CURRENT OF, видны в этом же курсоре. Tantor SE обрабатывает эти операторы так же, как и все другие операторы изменения данных, то есть они не видны в нерегистрозависимых курсорах.

Бинарные курсоры - это расширение Tantor SE.

См. также

CLOSE, FETCH, MOVE