DECLARE — определение курсора
DECLAREname[ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FORquery
DECLARE позволяет пользователю создавать курсоры, которые
могут использоваться для извлечения
небольшого количества строк за раз из более крупного запроса.
После создания курсора строки извлекаются из него с помощью
команды FETCH.
На этой странице описано использование курсоров на уровне SQL-команд. Если вы пытаетесь использовать курсоры внутри функции PL/pgSQL, правила отличаются — см. Раздел 5.6.7.
nameИмя создаваемого курсора. Оно должно отличаться от имён всех других активных курсоров в сеансе.
BINARYУказывает, что курсор должен возвращать данные в двоичном, а не в текстовом формате.
ASENSITIVEINSENSITIVE
Чувствительность курсора определяет, видны ли в курсоре изменения данных, лежащих в основе
курсора, выполненные в той же транзакции после объявления
курсора. INSENSITIVE
означает, что они не видны, ASENSITIVE означает, что
поведение зависит от реализации. Третье поведение,
SENSITIVE, означающее, что такие изменения видны в
курсоре, недоступно в Digital Q.DataBase.
В Digital Q.DataBase все курсоры нечувствительные;
поэтому эти ключевые слова не имеют эффекта и принимаются только для
совместимости со стандартом SQL.
Указание INSENSITIVE вместе с FOR
UPDATE или FOR SHARE является ошибкой.
SCROLLNO SCROLLSCROLL указывает, что курсор может использоваться
для извлечения строк не в последовательном порядке (например,
в обратном). В зависимости от сложности плана выполнения запроса
указание SCROLL может наложить
штраф на производительность времени выполнения запроса.
NO SCROLL указывает, что курсор нельзя
использовать для извлечения строк не в последовательном порядке. По умолчанию
прокрутка разрешена в некоторых случаях; это не то же самое, что указание
SCROLL. Подробности см. в Notes
ниже.
WITH HOLDWITHOUT HOLDWITH HOLD указывает, что курсор
можно продолжать использовать после успешного завершения транзакции, которая его создала.
WITHOUT HOLD указывает,
что курсор не может использоваться вне транзакции, которая
его создала. Если ни WITHOUT HOLD, ни
WITH HOLD не указаны, по умолчанию используется
WITHOUT HOLD.
query
Команда SELECT или
VALUES,
которая будет предоставлять строки, возвращаемые курсором.
Ключевые слова ASENSITIVE, BINARY,
INSENSITIVE и SCROLL могут
появляться в любом порядке.
Обычные курсоры возвращают данные в текстовом формате, таком же, какой
выдала бы команда SELECT. Параметр BINARY
указывает, что курсор должен возвращать данные в двоичном формате.
Это уменьшает усилия по преобразованию как на сервере, так и на клиенте,
ценой больших усилий программиста по работе с зависящими от платформы
двоичными форматами данных.
Например, если запрос возвращает значение единицы из целочисленного столбца,
при использовании курсора по умолчанию вы получите строку 1,
тогда как с двоичным курсором вы получите
4-байтовое поле, содержащее внутреннее представление значения
(в порядке байтов big-endian).
Двоичные курсоры следует использовать осторожно. Многие приложения, включая psql, не готовы обрабатывать двоичные курсоры и ожидают, что данные будут возвращаться в текстовом формате.
Когда клиентское приложение использует протокол «расширенного запроса»
для выполнения команды FETCH, в сообщении протокола Bind
указывается, должны ли данные извлекаться в текстовом или двоичном формате.
Этот выбор переопределяет то, как определён курсор. Таким образом, концепция
двоичного курсора как таковая устарела при использовании протокола расширенного запроса
— любой курсор может обрабатываться либо как текстовый, либо как двоичный.
Если не указан WITH HOLD, курсор,
созданный этой командой, может использоваться только в текущей
транзакции. Таким образом, DECLARE без WITH
HOLD бесполезен вне блока транзакции: курсор будет
существовать только до завершения оператора. Поэтому
Digital Q.DataBase сообщает об ошибке, если такая
команда используется вне блока транзакции.
Используйте команды
BEGIN и
COMMIT
(или ROLLBACK)
для определения блока транзакции.
Если указан WITH HOLD и транзакция,
создавшая курсор, успешно фиксируется, курсор может
продолжать использоваться последующими транзакциями в том же
сеансе. (Но если создающая транзакция прерывается, курсор
удаляется.) Курсор, созданный с WITH HOLD,
закрывается, когда на нём выполняется явная команда CLOSE
или когда сеанс завершается. В текущей реализации
строки, представленные удерживаемым курсором, копируются во временный
файл или область памяти, чтобы они оставались доступными для последующих
транзакций.
WITH HOLD не может быть указан, когда запрос
включает FOR UPDATE или FOR SHARE.
Параметр SCROLL должен быть указан при определении
курсора, который будет использоваться для выборки в обратном направлении.
Это требуется стандартом SQL. Однако для совместимости с более ранними
версиями Digital Q.DataBase позволяет
обратную выборку без SCROLL, если план запроса курсора
достаточно прост, чтобы не требовались дополнительные накладные расходы для поддержки
этого. Однако разработчикам приложений рекомендуется не полагаться на
обратную выборку из курсора, который не был создан
с SCROLL. Если указан NO SCROLL,
то обратная выборка запрещена в любом случае.
Обратная выборка также запрещена, когда запрос
включает FOR UPDATE или FOR SHARE; поэтому
в этом случае не может быть указан SCROLL.
Прокручиваемые курсоры могут давать неожиданные
результаты, если они вызывают какие-либо изменчивые (volatile) функции (см. Раздел 5.1.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. Сервер Digital Q.DataBase
не реализует оператор OPEN для
курсоров; курсор считается открытым, когда он объявлен.
Однако ECPG, препроцессор встроенного SQL
для Digital Q.DataBase, поддерживает
стандартные соглашения SQL о курсорах, включая те, которые связаны с
операторами DECLARE и OPEN.
Базовая структура данных сервера для открытого курсора называется
порталом. Имена порталов раскрываются в
клиентском протоколе: клиент может извлекать строки напрямую из открытого
портала, если знает имя портала. При создании курсора с помощью
DECLARE имя портала совпадает с
именем курсора.
Все доступные курсоры можно увидеть, запросив системное представление pg_cursors.
Чтобы объявить курсор:
DECLARE liahona CURSOR FOR SELECT * FROM films;
Другие примеры использования курсоров см. в FETCH.
Стандарт SQL допускает курсоры только во встроенном SQL и в модулях. Digital Q.DataBase позволяет использовать курсоры в интерактивном режиме.
Согласно стандарту SQL, изменения, внесённые в нечувствительные курсоры с помощью
операторов UPDATE ... WHERE CURRENT OF и DELETE
... WHERE CURRENT OF, видны в том же самом
курсоре. Digital Q.DataBase обрабатывает эти операторы так же, как
все другие операторы, изменяющие данные, в том смысле, что они не видны в
нечувствительных курсорах.
Двоичные курсоры являются расширением Digital Q.DataBase.