DECLARE

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


Синтаксис

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

Описание

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

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


Параметры

имя

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

BINARY

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

ASENSITIVE
INSENSITIVE

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

Указание INSENSITIVE вместе с FOR UPDATE или FOR SHARE является ошибкой.

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-байтовое поле, содержащее внутреннее представление значения (с сетевым порядком байтов).

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

Примечание
Когда клиентское приложение использует протокол «расширенный запрос» для выполнения команды 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 можно не указывать.

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

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


Примеры

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

DECLARE liahona CURSOR FOR SELECT * FROM films;

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


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

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

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

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


См. также

CLOSE, FETCH, MOVE