Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Metodichka_dlya_laboratornykh_rabot_BD.doc
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
2.57 Mб
Скачать

2.3. Курсоры

В хранимых процедурах и функциях поддерживаются простые курсоры.

Синтаксис такой же, как во встроенном SQL.

Оператор объявления курсора DECLARE

DECLARE имя_курсора CURSOR FOR onepaтop_sql

Во время процедуры можно определять многочисленные курсоры, но имя каждого из них должно быть уникальным

Оператор открытия курсора OPEN

OPEN имя_курсора

Данный оператор открывает объявленный ранее курсор.

Оператор выборки курсора FETCH

FETCH имя курсора INTO имя переменной [, имя_переменной] ...

Данный оператор выполняет выборку следующей строки (если строка существует) с помощью указанного открытого курсора и продвигает указатель курсора.

Оператор закрытия курсора CLOSE

CLOSE имя_курсора

Данный оператор закрывает открытый ранее курсор.

Конструкции управления потоком данных

К ним относятся операторы IF….THEN…ELSEIF, CASE, LOOP, WHILE, ITERATE и LEAVE. Каждая из этих конструкций может включать как единственный оператор, так и блок операторов, созданный с помощью составного оператора BEGIN ... END (см. выше).

Оператор IF

IF условие_поиска THEN оператор(ы)

[ELSEIF условие_поиска THEN оператор (ы)]

...

[ELSE оператор (ы)]

END IF;

IF реализует базовую конструкцию условия. Если значение условие_поиска является истинным, будет выполнен соответствующий SQL-оператор. Если совпадения с условие_поиска не найдены, выполняться будет оператор, указанный в конструкции ELSE.

Оператор CASE

CASE значение_сasе

WHEN значение_when THEN оператор

[WHEN значение_when THEN оператор ...]

[ELSE оператор]

END CASE;

или:

CASE

WHEN условие_поиска THEN оператор

[WHEN условие_поиска THEN оператор ...]

[ELSE оператор]

END CASE;

CASE реализует сложную конструкцию условия. Если значение условие_поиска является истинным, будет выполнен соответствующий SQL- оператор. Если совпадения с условие_поиска не найдены, выполняться будет оператор из конструкции ELSE.

Оператор LOOP

[метка__начала] LOOP

оператор (ы)

END LOOP [метка_конца]

LOOP реализует простую конструкцию цикла, допуская повторное выполнение какого-то конкретного оператора или группы операторов. Операторы в цикле повторяются до выхода из этого цикла, для чего обычно используется оператор LEAVE. Значения метка_начала и метка_конца, если заданы оба, должны быть одинаковыми.

Оператор LEAVE

LEAVE метка

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

Оператор ITERATE

ITERATE метка

ITERATE может появиться только при использовании операторов LOOP, REPEAT и WHILE. ITERATE означает "повторить цикл снова".

Рассмотрим соотвествующий пример:

CREATE PROCEDURE doiterate(pi INT)

BEGIN

labell: LOOP

SET pi = pi + 1;

IF pi < 10 THEN ITERATE labell; END IF;

LEAVE labell;

END LOOP labell;

SET @х = pi ;

END;

После того, как данная процедура будет успешно создана, следующие команды, выполненные из консоли:

CALL doiterate (10);

SELECT @x;

вернут:

Оператор REPEAT

[метка_начала:] REPEAT

оператор (ы)

UNTIL условие_поиска

END REPEAT [метка_конца];

Команды, указанные внутри оператора REPEAT, повторяются до тех пор, пока будет истинным условие условие_поиска. Значения метка_начала и метка_конца, если заданы оба, должны быть одинаковыми.

Рассмотрим пример:

CREATE PROCEDURE dorepeat(pi INT)

BEGIN

SET @x = 0;

REPEAT SET @x = @x + 1; UNTIL @x > pi END REPEAT;

END

После того, как данная процедура будет успешно создана, следующие

команды, выполненные из консоли:

CALL dorepeat (3);

SELECT @x;

Вернут:

Оператор WHILE

[метка начала:] WHILE условие_поиска DO

оператор (ы)

END WHILE [метка_конца];

Команды, указанные внутри оператора WHILE повторяются до тех пор, пока будет истинным условие условие_поиска. Значения метка_начала и метка_конца, если заданы оба, должны быть одинаковыми.

В качестве примера, обобщающего различные конструкции процедурного языка MySQL, решим с помощью хранимой процедуры следующую задачу по обработке данных в некоторой БД:

Состав студенческой группы меняется во времени, необходимо создать хранимую процедуру, которая нумеровала бы студентов в алфавитном порядке и сохраняла данный номер в базе данных (для этого к таблице students будет добавлено поле order_num).

Таблица students с учетом добавления поля принимает следующий вид:

CREATE TABLE `students` (

`student_id` int(11) NOT NULL auto_increment,

`group_id` int(11) default NULL,

`FirstName` varchar(20) default NULL,

`LastName` varchar(20) default NULL,

`order_num` int(11) default NULL,

PRIMARY KEY (`student_id`),

KEY `students_group_id` (`group_id`),

KEY `group_id` (`group_id`,`FirstName`),

CONSTRAINT `students_fk` FOREIGN KEY (`group_id`) REFERENCES

`groups` (`group_id`) ON DELETE NO ACTION

);

Соответствующая хранимая процедура sort_studens задается следующим

образом:

CREATE PROCEDURE `sort_studens`( IN _group_id INTEGER ( 11 ))

BEGIN

DECLARE done INT DEFAULT 0;

DECLARE ordercount INT DEFAULT 1;

DECLARE curstudent int;

DECLARE students_cur CURSOR FOR select student_id from students where

group_id = _group_id order by lastname, firstname;

DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

OPEN students_cur;

REPEAT

FETCH students_cur into curstudent;

update students set order_num = ordercount where student_id=curstudent;

SET ordercount = ordercount + 1;

UNTIL done END REPEAT;

CLOSE students_cur;

END;

Здесь параметр done используется как критерий останова (02000 – попытка прочесть запись из курсора все записи в котором прочтены). Обратите внимание, что имя входного параметра не должно совпадать с полем по которому идет сравнение, в случае если входной параметр используется в курсоре (в данном случае входной параметр _group_id не должен совпадать с group_id, так как в противном случае, в курсор будут помещены все записи из таблицы).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]