Циклы
Другую категорию команд, передающих управление внутри функций, составляют циклы. В циклах используются разные виды итераций, предназначенные для решения разных задач. Итеративные вычисления значительно расширяют возможности функций PL/pgSQL.
В PL/pgSQL реализованы три типа циклов: простейший (безусловный) цикл, цикл WHILE и цикл FOR. Вероятно, из этих трех циклов чаще всего применяется цикл FOR, подходящий для широкого круга задач программирования, хотя и другие циклы также достаточно часто встречаются на практике.
Безусловный цикл
Ключевое слово LOOP начинает простейший безусловный цикл. Команды безусловного цикла выполняются до тех пор, пока не будет достигнуто ключевое слово EXIT. За ключевым словом EXIT может следовать секция WHEN с выражением, определяющим условие выхода. Выражение должно относиться к логическому типу. Например, оно может проверять, достигла ли переменная некоторой величины. Ниже приведен синтаксис безусловного цикла (без ключевого слова LOOP):
LOOP команде: […] END LOOP:
Команда EXIT завершает работу безусловного цикла и может дополнительно содержать метку и/или условие завершения.
Метка представляет собой произвольный идентификатор, заключенный между префиксом " и суффиксом ". Чтобы назначить метку циклу, следует расположить ее непосредственно перед началом цикла. Синтаксис определения цикла с меткой:
"метка" LOOP […] END LOOP:
Назначение метки циклу позволяет указать нужный цикл при выходе из нескольких вложенных циклов (команда EXIT с меткой работает лишь в том случае, если завершаемому циклу была присвоена соответствующая метка).
Если команда EXIT содержит условие, цикл прерывается только в том случае, если это условие истинно.
Синтаксис вызова EXIT в цикле LOOP:
[ "метка" ] LOOP statement; […] EXIT [ метка ] [ WHEN условие ]: END LOOP:
В листинге 11.42 приведен пример безусловного цикла и команды EXIT, завершающей цикл при выполнении некоторого условия. Функция square_integer_loop() возводит целое число в квадрат (умножает его само на себя) до тех пор, пока его значение не превысит 10 000, после чего возвращает полученный результат.
Листинг 11.42. Использование безусловного цикла.
CREATE FUNCTION square_integer_loop (integer) RETURNS integer AS ' DECLARE --Объявление псевдонима для аргумента, numl ALIAS FOR $1; – Объявление целочисленной переменной для хранения результата, result integer; BEGIN – Исходное число присваивается переменной result, result: = numl; LOOP result: = result * result: EXIT WHEN result >= 10000; END LOOP; RETURN result: END; ' LANGUAGE 'plpgsql';
В листинге 11.43 показан результат вызова square_integer_loop() с аргументом 3.
Листинг 11.43. Результат вызова функции square_integer_loop().
booktown=# SELECT square_integer_loop(3); squa re_i nteger_l oop 6561 (1 row)