Циклы в хранимых процедурах используются, когда необходимо выполнить один и тот же запрос более одного раза. В MySQL для создания циклов применяют операторы LOOP, REPEAT и WHILE.
Оператор цикла WHILE
Выполнение запроса будет продолжаться до тех пор, пока условие будет истинным.
Рассмотрим пример.
Пусть необходимо узнать авторов, названия и количество книг, поступивших в различные поставки. Нужная информация сохраняется в таблице magazine_incoming (Журнал Поставок) и таблице products (Товар).
Код запроса будет выглядеть следующим образом:
При необходимости вывода результата не в одну таблицу, а по каждой поставке отдельно, можно записать три разных запроса с добавлением в каждый еще одного условия:
Намного меньшим код будет с использованием цикла WHILE:
Переменная i по умолчанию равна 3. Сервером будет выполнен запрос с id поставки = 3, затем i будет уменьшена на единицу (SET i=i-1), выполнена проверка нового значения переменной i (что оно положительно (i>0)) и снова выполнен запрос, но с другим значением id поставки = 2. Такой процесс будет продолжаться до тех пор, пока переменная i не станет равна 0. Тогда условие будет ложным и цикл прекратиться. Убедимся в работоспособности цикла, создав хранимую процедуру books и поместив в нее цикл:
Вызов процедуры:
Теперь получено три отдельные таблицы (по каждой поставке).
Очевидно, что код с циклом намного меньше трех отдельных запросов. Недостаток написанной процедуры в том, что количество выводимых таблиц объявлено значением по умолчанию (DEFAULT 3), и с каждой новой поставкой придется изменять это значение, т.е. изменять код процедуры. Намного удобнее это число сделать входным параметром.
Перепишем созданную процедуру, добавим входной параметр num и учтем, что он не может быть равен нулю:
Если пользователь задаст очень большое входное значение, то получится псевдобесконечный цикл, который загружает сервер бесполезной работой. Чтобы избежать подобных ситуаций, цикл снабжается меткой и используется оператор LEAVE, который обозначает досрочный выход из цикла.
В цикл была добавлена метка wet вначале (wet:) и в конце, и добавлено еще одно условие – при входном параметре более 10 (число 10 – произвольное) цикл с меткой wet нужно завершить (IF (i>10) THEN LEAVE wet). Следовательно, если пользователь случайно задаст большое значение num, то цикл завершится после 10 итераций (проходов цикла).
В практической деятельности циклы в MySQL, как и операторы ветвления, в web-приложениях очень редко используются. Приведем синтаксис других видов цикла.
Оператор цикла REPEAT
Условие цикла проверяется в конце, а не в начале, как в цикле WHILE. Таким образом, цикл выполняется как минимум 1 раз. К тому же цикл будет выполняться до тех пор, пока условие ложно.
Синтаксис оператора:
Оператор цикла LOOP
Цикл совершенно не содержит условий, поэтому обязательно должен содержать оператор LEAVE.
Синтаксис оператора:
Циклы являются живым компонентом процедуры. С их помощью можно определенный участок кода повторять нужное количество раз. Наиболее часто используется цикл WHILE, в котором блок операторов повторяется до тех пор, пока условие истинно.
Выражение в цикле REPEAT повторяется до тех пор, пока условие Until ложно.
Цикл REPEAT отличается от цикла While еще и тем, что данный цикл выполняется хотя бы один раз.