DECLARE

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

Синтаксис

DECLARE имя [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]
    CURSOR [ { WITH | WITHOUT } HOLD ] FOR запрос

Описание

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

Примечание
Эта страница описывает использование курсоров на уровне команд SQL. Если вы пытаетесь использовать курсоры внутри функции PL/pgSQL, правила будут другими — см. раздел Структура PL/pgSQL.

Параметры

имя

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

BINARY

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

INSENSITIVE

Указывает, что данные, извлеченные из курсора, не должны быть затронуты обновлениями таблиц(ы), лежащей(их) в основе курсора, которые происходят после его создания. В QHB это поведение по умолчанию, поэтому данное ключевое слово не имеет никакого эффекта и принимается только для совместимости со стандартом SQL.

SCROLL
NO SCROLL

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

WITH HOLD
WITHOUT HOLD

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

запрос

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

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

Примечания

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

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

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

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

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

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

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

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

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

Если запрос в определении курсора включает указания FOR UPDATE или FOR SHARE, возвращаемые курсором строки блокируются в момент первой выборки, аналогично происходящему при выполнении обычной команды SELECT с этими указаниями. Кроме того, возвращаемые строки будут самыми актуальными версиями; поэтому эти параметры обеспечивают эквивалент того, что стандарт SQL называет «чувствительным курсором». (Указание INSENSITIVE для курсора с запросом FOR UPDATE или FOR SHARE является ошибкой.)

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

Примеры

Чтобы объявить курсор:

DECLARE liahona CURSOR FOR SELECT * FROM films;

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

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

Стандарт SQL говорит, что чувствительность курсоров к параллельному обновлению нижележащих данных по умолчанию определяется реализацией. В QHB курсоры по умолчанию нечувствительны и могут быть сделаны чувствительными путем указания FOR UPDATE. Другие СУБД могут работать по-другому.

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

Бинарные курсоры являются расширением QHB.

См. также

CLOSE, FETCH, MOVE