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, она представляет собой весьма наглядный пример обработки результирующего множества.
Таким образом, анализ возможностей хранимых процедур показал, что их использование как общего ресурса баз данных позволяет унифицировать обработку содержимого баз данных и повысить эффективность функционирования приложений.
Назад | Содержание | Вперед