WHILE

Оператор WHILE

Оператор WHILE виконує цикл і має наступний синтаксис:

[label:] while search_condition DO

statement_list

END while [label]

Цикл WHILE виконує оператори statement_list до тих пір, поки умова search_condition істинна. При кожній ітерації умова search_condition перевіряється, і якщо при черговій перевірці воно буде хибним (0), цикл завершить своє виконання. Це означає, що якщо умова search_condition хибна з самого початку, цикл не виконає жодної ітерації.

Якщо в циклі потрібно виконати більше одного оператора, не обов'язково укладати, їх у блок BEGIN ... END, т. к. цю функцію виконує сам оператор WHILE. Виведемо 3 рази поточну дату за допомогою циклу WHILE (приклад).

Приклад:

CREATE PROCEDURE NOW5()

LANGUAGE SQL

BEGIN

DECLARE i INT DEFAULT 3;

WHILE i > 0 DO

SELECT NOW();

SET i = i - 1;

END WHILE;

END //

 

CALL NOW5()//

NOW()

2005-07-18 12:36:59

NOW()

2005-07-18 12:36:59

NOW()

2005-07-18 12:36:59

Перший оператор в циклі WHILE виводить поточну дату, а другий віднімає з локальної змінної i одиницю. Якщо одиницю не віднімати, то утворюється нескінченний цикл, з якого процедура ніколи не вийде, а буде марно навантажувати сервер, поки сеанс з ним не припиниться. Варто дуже уважно проектувати цикли, щоб запобігти нескінченні цикли.

У прикладі нижче представлений код збереженої процедури, яка виводить поточну дату num число раз, де num - параметр, що задається користувачем.

Приклад:

CREATE PROCEDURE NOWN (IN num INT)

LANGUAGE SQL

BEGIN

DECLARE i INT DEFAULT 0;

IF (num > 0) THEN wet : WHILE i < num DO SELECT NOW();

SET i = i + 1;

END WHILE wet;

ELSE

SELECT 'Помилкове значення параметра';

END IF;

END //

CALL NOWN(2)//

NOW ()

2005-07-18 12:51:27

NOW ()

2005-07-18 12:51:27

Як видно з попереднього прикладу, цикл WHILE іменований міткою wet. Мітка в циклі призначена не тільки для того, щоб полегшити читання коду при дуже довгих циклах, вона дозволяє здійснювати достроковий вихід з циклу.

Для дострокового виходу з циклу призначений оператор LEAVE, який має наступний синтаксис:

LEAVE label

Оператор LEAVE припиняє виконання блоку, позначеного міткою label.

Зауваження:

  • Оператор LEAVE еквівалентний оператору break в С-подібних мовах програмування

Процедура NOWN () має недолік - якщо задати дуже велике значення аргументу num, можна створити псевдобескінечний цикл, який дозволить зловмиснику завантажити сервер марною роботою. Для запобігання такої ситуації можна скористатися оператором LEAVE, який припинить виконання никла після досягнення критичної числа ітерацій. У лістингу нижче наводиться приклад збереженої процедури, де число ітерації обмежена двома.

Приклад:

CREATE PROCEDURE NOWN (IN num INT)

LANGUAGE SQL

BEGIN

DECLARE i INT DEFAULT 0;

IF (num > 0) THEN

wet : WHILE i < num DO

IF i > 2 THEN LEAVE wet;

END IF;

SELECT N0W();

SET i = i + 1;

END WHILE wet;

ELSE

SELECT 'Помилкове значення параметра';

END IF;

END //

CALL NOWN(10)//

NOW()

2005-07-18 12:51:27

NOW()

2005-07-18 12:51:27

Умова if i> 2 then leave wet; перевіряє, чи не перевищило значення лічильника i число 2, і якщо це так, відбувається припинення циклу while. Використання міток дозволяє точно вказати, який цикл необхідно перервати. Якщо є вкладений цикл, можна явно вказати, який з двох циклів потрібно перервати (приклад).

Приклад:

first : WHILE i < num DO

second : WHILE j < num DO

IF i > 2 && j > 2 THEN LEAVE first;

END IF;

SELECT NOW();

SET j = j + 1;

END WHILE second;

SET i = i + 1;

END WHILE first;

При досягненні умови i> 2 & & j> 2 оператор LEAVE перерве не вкладений цикл second, а зовнішній цикл first, т. к. мітка зовнішнього циклу явно вказана після оператора.

При використанні дострокового виходу LEAVE можна навіть використовувати нескінченні цикли, тому що рано чи пізно зовнішній цикл буде завершений (приклад).

Приклад:

first : WHILE 1 DO

second : WHILE 1 DO

IF i > 2 && j > 2 THEN LEAVE first;

END IF; SELECT NOW();

SET j = j + 1;

END WHILE second;

SET i - i + 1;

END WHILE first;

Цифра 1 в умові циклу завжди буде істинною і цикл не припиниться до тих пір, поки його не перерве оператор LEAVE.