Инструменты пользователя

Инструменты сайта


Боковая панель

Введение

Статьи и часто задаваемые вопросы

Установка и настройка

Обработка ошибок

Полезные запросы SQL

Тематические группы

declare_cursor

DECLARE CURSOR

Версии сервера

0.9 1.0 1.5.3 1.5.4 1.5.5 2.0 2.0.3 2.0.4 2.1 2.5 3.0
DSQL - - Да Да Да Да Да Да Да Да Да
PSQL - - - - - Да Да Да Да Да Да

Формат

SQL:

DECLARE cursor CURSOR FOR <select> [FOR UPDATE OF <col> [, <col>...]];

DSQL:

DECLARE cursor CURSOR FOR <statement_id>

BLOB: DECLARE CURSOR(BLOB)

PSQL (:!: Firebird v2.0 и выше):

DECLARE [VARIABLE] <cursor_name> CURSOR FOR (<select_statement>);
Аттрибут Значение
<cursor_name> Имя переменной курсора. К нему применимы правила объявления локальных переменных в PSQL
<select_statement> Оператор выбора набора данных SELECT

Описание

DECLARE CURSOR определяет набор данных, который может быть возвращен, при обращении к этому курсору. Это первая инструкция, из группы инструкций работы с курсором, которая должна быть использована в работе с ним.

<select> определяет инструкцию SELECT, которая определяет, какой набор данных необходимо вернуть. Инструкция SELECT не должна включать предложения INTO и ORDER BY.

Предложение FOR UPDATE OF необходимо, для модификации или удаления значений из набора данных.

Курсор это однонаправленный указатель на упорядоченный набор данных, возвращенных выражением SELECT в инструкции DECLARE CURSOR, позволяющий получить последовательный однонаправленный доступ к возвращенным даныым.

Есть четыре связанных инструкции для работы с курсором:

Стадия Инструкция Назначение
1 DECLARE CURSOR Объявляет курсор. Инструкция SELECT определяет набор данных, возвращаемый для курсора.
2 OPEN Открывает набор данных на последовательный однонаправленный доступ.
3 FETCH Возвращает текущую строку из текущего набора данных, начиная с первой строки.
4 CLOSE Закрывает курсор и освобождает системные ресурсы.

Эта инструкция может быть использована в SQL, DSQL, PSQL. :!: Для работы с курсорами в PSQL нужно использовать Firebird v2.0 и выше.

:!: Важные замечания для работы с FETCH, OPEN, CLOSE, DECLARE CURSOR в PSQL:

замечание
1 Объявление курсора как переменной DECLARE CURSOR разрешается только в области объявления переменных DECLARE VARIABLE PSQL-блока/хранимой процедуры/триггера.
2 Имена курсоров должны быть уникальны в текущем контексте. They cannot interfere with FOR SELECT cursor (declared via the AS CURSOR clause) names. But a cursor can share its name with any variable in this context, as possible operations are different.
3 Операция обновления и удаления в курсоре использует WHERE CURRENT OF clause are allowed.
4 Попытки извлечения данных или закрытия (вызова оператора CLOSE) FOR SELECT курсора запрещены !
5 Попытки открыть курсор, который уже открыт при помощи оператора OPEN, а равно, как и попытки FETCH из закрытого курсора, который не был открыт при помощи оператора OPEN или закрыт оператором CLOSE, будут неудачными.
6 Все курсоры, котрые не были явно закрыты при помощи оператора CLOSE при выходе из PSQL-блока/хранимой процедуры/триггера автоматически закрываются
7 Системная контекстная переменная ROW_COUNT может быть использована для проверки, вернул ли очередной FETCH строку
8 SELECT запрос может содержать имена параметров, например: “select name from names where number = :num” Каждый параметр должен быть ранее объявленной переменной (включая входящие/выходящие параметры процедуры). Когда курсор открывается - параметры получают текущее значенее одноименных переменных.

Пример

Следующая внедренная инструкция SQL объявляет курсор с условиями поиска:

EXEC SQL
  DECLARE C CURSOR FOR
  SELECT CUST_NO, ORDER_STATUS
  FROM SALES
  WHERE ORDER_STATUS IN ("open", "shipping");

Следующая инструкция DSQL объявляет курсор для предварительно приготовленной инструкции QUERY1:

DECLARE Q CURSOR FOR QUERY1

PSQL: Следующий пример показывает принципы работы с FETCH, DECLARE CURSOR, OPEN, CLOSE, ROW_COUNT в PSQL.

SET TERM !!;

CREATE OR ALTER PROCEDURE GET_RELATIONS_NAMES 
RETURNS(
  RNAME CHAR(31)
)AS
  DECLARE C CURSOR FOR (SELECT RDB$RELATION_NAME FROM RDB$RELATIONS);
BEGIN
  OPEN C;
  WHILE (1 = 1) DO
  BEGIN
    FETCH C INTO :RNAME;
    IF(ROW_COUNT = 0)THEN
      LEAVE;
    SUSPEND;
  END
  CLOSE C;
END!!

SET TERM ;!!

См. также

Источник

langref.pdf

Обсуждение

MNF, 2009/04/17 12:34

ИМХО, без WHILE(1 = 1) будет красивее

SET TERM !!;
 
CREATE OR ALTER PROCEDURE GET_RELATIONS_NAMES 
RETURNS(
  RNAME CHAR(31)
)AS
  DECLARE C CURSOR FOR (SELECT RDB$RELATION_NAME FROM RDB$RELATIONS);
BEGIN
  OPEN C;
  FETCH C INTO :RNAME;
  WHILE (ROW_COUNT > 0) DO
  BEGIN
    SUSPEND;
    FETCH C INTO :RNAME;
  END
  CLOSE C;
END!!
 
SET TERM ;!!
afgm, 2009/08/05 21:41

Вариант WHILE (1 = 1) призван избежать дублирования код в части FETCH C INTO :RNAME

Makaracho, 2011/12/09 21:31
Только авторизованные участники могут оставлять комментарии.
declare_cursor.txt · Последние изменения: 2015/11/11 11:00 — commanderz