6.3. Использование курсоров в хранимых процедурах
Одним из способов возврата результатов работы хранимых процедур является формирование результирующего множества. Данное множество формируется при выполнении оператора SELECT. Оно записывается во временную таблицу - курсор. Применение курсора в процедурах осуществляется путем последовательного выполнения следующих шагов:
По умолчанию курсор закрывается автоматически в конце транзакции (операторы COMMIT или ROLLBACK). Если при объявлении курсора указана фраза WITH HOLD (с сохранением), то курсор закрывается только явным образом оператором CLOSE. Такое использование курсора снимает все проблемы с остановкой функционирования процедур в среде утилиты ISQL, формирующих результирующие множества. В этом случае отпадает необходимость использования оператора RESUME.
В курсоре указатель может быть установлен:
В соответствие с приведенными шагами рассмотрим пример обработки результатов работы процедуры Get_list_absent. Для этого создадим в учебных целях процедуру Count_publishers, которая для читателя по фамилии "Петрова В.А.", имеющей читательскую карточку с № 80, определяет количество книг, изданных в издательстве "Советское радио". Текст этой процедуры приводится ниже:
//Процедура, использующая обработку курсора
CREATE PROCEDURE Count_publishers
/* Процедура подсчитывает количество книг
взятых, читателем "Петрова В.А.", которые
изданы в издательстве "Советское радио" */
(
OUT Par_count_publishers SMALLINT
)
BEGIN
DECLARE Err_not_found //Декларируем
EXCEPTION FOR //ситуацию выхода
SQLSTATE '02000'; //за пределы курсора
DECLARE
N_Petrova SMALLINT; //№ читательской
//карточки читателя "Петрова В.А."
// Объявление переменных для хранения
// значений полей текущей записи курсора
DECLARE Tek_Author CHAR(20);
DECLARE Tek_Title_book CHAR(100);
DECLARE Tek_City_publish CHAR(15);
DECLARE Tek_Publisher CHAR(20);
DECLARE Tek_Year_publish SMALLINT;
DECLARE //Объявление курсора Rez_cursor
Rez_cursor // для результирующего множества,
CURSOR FOR //формируемого процедурой
CALL Get_list_absent(N_Petrova);
SET //Обнуляем счетчик взятых книг
Par_count_publishers = 0;
/* Определяем № читательской карточки
читателя Петровой В.А. */
SELECT Reader.N_reader
INTO N_Petrova
FROM Stepanov.Reader
WHERE Reader.Name_reader =
'Петрова В.А.';
//Открываем курсор Rez_cursor с
//результирующим множеством
// процедуры Get_list_absent
OPEN Rez_cursor;
//Последовательно обрабытываем все
//записи курсора Rez_cursor
Work_for_kurs_loop: //метка цикла
LOOP
//Перемещаем указатель текущей записи
//курсора на следующую запись. При этом
//содержимое все полей записываются в
//предназначенне для этого переменные
FETCH NEXT Rez_cursor
INTO Tek_Author, Tek_Title_book,
Tek_City_publish, Tek_Publisher,
Tek_Year_publish;
IF SQLSTATE = Err_not_found
THEN //В случае если произошел выход за
//пределы курсора, то завершается
//работа цикла Work_for_kurs_loop
LEAVE Work_for_kurs_loop;
END IF;
IF Tek_Publisher = 'Советское радио'
THEN
SET Par_count_publishers=
Par_count_publishers+1;
END IF;
END LOOP Work_for_kurs_loop;
//конец цикла
CLOSE Rez_cursor;
END
Чтобы убедиться в правильной работе процедуры Count_publishers необходимо выполнить следующие SQL-операторы:
//Проверка работы процедуры Count_publishers //CREATE VARIABLE Rez SMALLINT; CALL Count_publishers(Rez); SELECT Rez
В результате вызова этой процедуры в переменную Rez записано значение один.
Несмотря на ограниченное применение процедуры Count_publishers, она представляет собой весьма наглядный пример обработки результирующего множества.
Таким образом, анализ возможностей хранимых процедур показал, что их использование как общего ресурса баз данных позволяет унифицировать обработку содержимого баз данных и повысить эффективность функционирования приложений.
Назад | Содержание | Вперед