ГЛАВА 3
----------------------------------------------------------------
УПРАВЛЯЮЩИЕ СТРУКТУРЫ
One ship drives east and another drives west
With the selfsame winds that blow.
'Tis the set of the sails and not the gales
Which tells us the way to go.
Ella Wheeler Wilcox
(Кто едет на запад, а кто - на восток,
А ветер - один на всех.
Не ветер, а парус, ткани кусок,
Диктует твой путь и успех.
Элла Уилер Уилкокс)
Эта глава показывает, как структурировать поток управления через
программу PL/SQL. Вы узнаете, как соединяются предложения с
помощью простых, но мощных управляющих структур, каждая из
которых имеет единственную точку входа и выхода. В
совокупности, эти структуры позволяют обработать любую ситуацию.
А их правильное использование естественно приводит к хорошо
структурированной программе.
Управляющие структуры 3-1
----------------
Обзор
Согласно ТЕОРЕМЕ О СТРУКТУРАХ, любая компьютерная программа
может быть написана с использованием трех основных управляющих
структур, показанных на рис.3-1. Эти структуры можно
комбинировать любым способом, необходимым для решения данной
проблемы.
Рис.3-1
Управляющие структуры
ВЫБОР ИТЕРАЦИЯ ПОСЛЕДОВАТЕЛЬНОСТЬ
¦ ¦ ¦
T г---+---¬ F г---+---¬ F ----+---¬
----¦ ¦---¬ ---¦ ¦---¬ ¦ ¦
¦ L-------- ¦ ¦ L---T---- ¦ L---T----
¦ T ¦
----+---¬ ----+---¬ ¦ ----+---¬ ¦ ----+---¬
¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦
L---T---- L---T---- ¦ L---T---- ¦ L---T----
¦ --¬ ¦ ¦ ¦
L-----+ +------ L-------- ----+---¬
LT- ¦ ¦
L---T----
Структура выбора проверяет условие и в зависимости от его
истинности выбирает одну или другую последовательность
предложений. УСЛОВИЕ - это любая переменная или выражение,
возвращающее булевское значение (TRUE, FALSE или NULL).
Структура итерации повторно выполняет последовательность
предложений, пока условие остается истинным. Структура
последовательности просто выполняет последовательность
предложений в том порядке, в котором они встречаются.
Теперь взглянем на эти структуры ближе.
----------------
Условное управление: предложения IF
Часто бывает необходимо предпринять альтернативные действия в
зависимости от обстоятельств. Предложение IF позволяет вам
выполнить последовательность предложений условно. Это значит,
что, будет выполнена эта последовательность или нет, зависит от
значения условия. Есть три формы предложений IF: IF-THEN,
IF-THEN-ELSE и IF-THEN-ELSIF.
IF-THEN
-------
Простейшая форма предложения IF ассоциирует условие с
последовательностью предложений, окружаемой ключевыми словами
THEN и END IF (не ENDIF), как показано ниже:
IF условие THEN
ряд_предложений;
END IF;
3-2 Руководство пользователя и справочник по PL/SQL
Последовательность предложений выполняется, только если условие
дает TRUE. Если условие дает FALSE или NULL, то предложение IF
ничего не делает. В любом случае, управление передается на
следующее предложение. Пример:
IF sales > quota THEN
compute_bonus(emp_id);
UPDATE payroll SET pay = pay + bonus WHERE empno = emp_id;
END IF;
Вы можете, если хотите, записывать короткие предложения IF в
одну строку, например:
IF x > y THEN high := x; END IF;
IF-THEN-ELSE
------------
Вторая форма предложения IF добавляет ключевое слово ELSE, за
которым следует альтернативная последовательность предложений:
IF условие THEN
ряд_предложений1;
ELSE
ряд_предложений2;
END IF;
Последовательность предложений в фразе ELSE выполняется, только
если условие дает FALSE или NULL. Таким образом, фраза ELSE
гарантирует, что одна из последовательностей предложений будет
выполнена. В следующем примере, первое или второе предложение
UPDATE будет выполнено, когда условие соответственно истинно или
ложно:
IF trans_type = 'CR' THEN
UPDATE accounts SET balance = balance + credit WHERE ...
ELSE
UPDATE accounts SET balance = balance - debit WHERE ...
END IF;
Последовательности предложений, включаемые в фразы IF и ELSE,
сами могут содержать предложения IF. Следовательно, предложения
IF могут вкладываться друг в друга, как показывает следующий
пример:
IF trans_type = 'CR' THEN
UPDATE accounts SET balance = balance + credit WHERE ...
ELSE
IF new_balance >= minimum_balance THEN
UPDATE accounts SET balance = balance - debit WHERE ...
ELSE
RAISE insufficient_funds;
END IF;
END IF;
Управляющие структуры 3-3
IF-THEN-ELSIF
-------------
Иногда вы хотите выбрать действие из нескольких взаимно
исключающих альтернатив. Третья форма предложения IF использует
ключевое слово ELSIF (не ELSE IF), чтобы ввести дополнительные
условия:
IF условие1 THEN
ряд_предложений1;
ELSIF условие2 THEN
ряд_предложений2;
ELSE
ряд_предложений3;
END IF;
Если первое условие дает FALSE или NULL, фраза ELSIF проверяет
следующее условие. В предложении IF может быть сколько угодно
фраз ELSIF; последняя фраза ELSE необязательна. Условия
вычисляются по одному сверху вниз. Если любое условие даст
TRUE, выполняется соответствующая последовательность
предложений, и управление передается на следующее за IF
предложение (без вычисления оставшихся условий). Если все
условия дадут FALSE или NULL, выполняется последовательность
предложений в фразе ELSE, если она есть. Рассмотрим следующий
пример:
IF sales > 50000 THEN
bonus := 1500;
ELSIF sales > 35000 THEN
bonus := 500;
ELSE
bonus := 100;
END IF;
INSERT INTO payroll VALUES (emp_id, bonus, ...);
Если значение sales превышает 50000, истинны как первое, так и
второе условия. Тем не менее, переменной bonus присваивается
правильное значение 1500, потому что второе условие проверяться
не будет, а управление сразу будет передано на предложение
INSERT.
3-4 Руководство пользователя и справочник по PL/SQL
Советы
------
Избегайте неуклюжих предложений IF, подобных следующему примеру:
DECLARE
...
overdrawn BOOLEAN;
BEGIN
...
IF new_balance < minimum_balance THEN
overdrawn := TRUE;
ELSE
overdrawn := FALSE;
END IF;
...
IF overdrawn = TRUE THEN
RAISE insufficient_funds;
END IF;
END;
Этот код игнорирует два полезных факта. Во-первых, значение
булевского выражения можно непосредственно присваивать булевской
переменной. Так, первое предложение IF можно заменить простым
присваиванием:
overdrawn := new_balance < minimum_balance;
Во-вторых, булевская переменная сама имеет значение TRUE либо
FALSE. Поэтому условие во втором предложении IF можно
упростить:
IF overdrawn THEN ...
По мере возможности, используйте фразу ELSIF вместо вложенных
предложений IF. При этом ваш код будет легче читать и понимать.
Сравните следующие предложения IF:
IF условие1 THEN | IF условие1 THEN
предложение1; | предложение1;
ELSE | ELSIF условие 2 THEN
IF условие2 THEN | предложение2;
предложение2; | ELSIF условие3 THEN
ELSE | предложение3;
IF условие3 THEN | END IF;
предложение3; |
END IF; |
END IF; |
END IF; |
Эти предложения логически эквивалентны, но первое из них
затемняет логику, тогда как второе проявляет ее.
Управляющие структуры 3-5
----------------
Итеративное управление: Предложения LOOP и EXIT
Предложения LOOP позволяют выполнить последовательность
предложений несколько раз. Есть три формы предложения LOOP:
LOOP, WHILE-LOOP и FOR-LOOP.
LOOP
----
Простейшую форму предложения LOOP представляет основной (или
бесконечный) цикл, который окружает последовательность
предложений между ключевыми словами LOOP и END LOOP:
LOOP
ряд_предложений
END LOOP;
При каждой итерации цикла последовательность предложений
выполняется, а затем управление передается на начало цикла.
Если дальнейшее повторение нежелательно или невозможно, вы
можете использовать предложение EXIT, чтобы закончить цикл. Вы
можете поместить сколько угодно предложений EXIT внутри цикла,
но только не вне цикла. Есть две формы предложения EXIT: EXIT и
EXIT WHEN.
EXIT
Предложение EXIT форсирует безусловное завершение цикла. Когда
встречается предложение EXIT, цикл немедленно заканчивается, и
управление передается на следующее (за END LOOP) предложение.
Пример:
LOOP
...
IF ... THEN
...
EXIT; -- немедленно выходит из цикла
END IF;
END LOOP;
-- управление передается сюда
Как показывает следующий пример, вы не можете использовать
предложение EXIT, чтобы завершить блок PL/SQL:
BEGIN
...
IF ... THEN
...
EXIT; -- незаконно
END IF;
END;
Не забывайте, что предложение EXIT можно применять только внутри
цикла. Чтобы выйти из блока PL/SQL до достижения его
нормального конца, можно использовать предложение RETURN (см.
главу 9).
3-6 Руководство пользователя и справочник по PL/SQL
EXIT-WHEN
Предложение EXIT-WHEN позволяет завершить цикл условно. Когда
встречается это предложение, вычисляется условие в фразе WHERE.
Если это условие дает TRUE, цикл завершается, и управление
передается на предложение, следующее за циклом. Пример:
LOOP
FETCH c1 INTO ...
EXIT WHEN c1%NOTFOUND; -- выйти из цикла при условии
...
END LOOP;
CLOSE c1;
Пока условие не станет истинным, цикл не может завершиться.
Поэтому, предложения внутри цикла должны изменять значение
условия. В последнем примере, если предложение FETCH извлекает
строку, условие дает FALSE. Когда предложение FETCH не сможет
возвратить строку, условие даст TRUE, цикл завершится, и
управление будет передано на предложение CLOSE.
Предложение EXIT-WHEN заменяет простое предложение IF. Например,
сравните следующие предложения:
IF count > 100 THEN | EXIT WHEN count > 100;
EXIT; |
END IF; |
Эти предложения логически эквивалентны, но предложение EXIT-WHEN
легче читается и понимается.
Метки циклов
Как и блоки PL/SQL, циклы могут иметь метки. Метка,
необъявляемый идентификатор в двойных угловых скобках, должна
появиться в начале предложения LOOP:
<<имя_метки>>
LOOP
ряд_предложений
END LOOP;
Имя метки цикла может также (необязательно) появиться в конце
цикла в предложении END LOOP, как показывает следующий пример:
<>
LOOP
...
END LOOP my_loop;
Когда вы используете вложенные циклы, конечные метки циклов
улучшают читабельность программы.
Управляющие структуры 3-7
Обе формы предложения EXIT позволяют выйти не только из текущего
цикла, но из любого окружающего цикла. Просто дайте метку тому
циклу, который вы хотите завершить, а затем укажите эту метку в
предложении EXIT:
<>
LOOP
...
LOOP
...
EXIT outer WHEN ... -- выйти из обоих циклов
END LOOP;
...
END LOOP outer;
Выход осуществляется из всех окружающих циклов, вплоть до того,
чья метка специфицирована в предложении EXIT.
WHILE-LOOP
----------
Предложение WHILE-LOOP ассоциирует условие с последовательностью
предложений, окруженной ключевыми словами LOOP и END LOOP:
WHEN условие LOOP
ряд_предложений;
END LOOP;
Перед каждой итерацией цикла условие проверяется. Если оно дает
TRUE, то последовательность предложений выполняется, и
управление возвращается на начало цикла. Если условие дает
FALSE или NULL, то цикл обходится, и управление передается на
следующее предложение. Пример:
WHILE total <= 25000 LOOP
...
SELECT sal INTO salary FROM emp WHERE ...
total := total + salary;
END LOOP;
Число повторений цикла зависит от условия и неизвестно до тех
пор, пока цикл не завершится. Поскольку условие проверяется в
начале цикла, последовательность предложений может не
выполниться ни разу. В последнем примере, если начальное
значение переменной total окажется больше 25000, условие даст
FALSE, и цикл будет обойден.
3-8 Руководство пользователя и справочник по PL/SQL
В некоторых языках имеется структура LOOP UNTIL или REPEAT
UNTIL, которая проверяет условие не в начале, а в конце итерации
цикла. Поэтому гарантируется хотя бы однократное выполнение
тела цикла. В PL/SQL такой структуры нет, но вы легко можете ее
смоделировать:
LOOP
ряд_предложений;
EXIT WHEN булевское_выражение;
END LOOP;
Чтобы гарантировать хотя бы однократное выполнение цикла WHILE,
используйте в условии инициализированную булевскую переменную:
done := FALSE;
WHILE NOT done LOOP
ряд_предложений;
done := булевское_выражение;
END LOOP;
Какое-то предложение внутри цикла должно присвоить булевской
переменной новое значение. В противном случае вы получите
бесконечный цикл. Например, следующие предложения LOOP
логически эквивалентны:
WHILE TRUE LOOP | LOOP
... | ...
END LOOP; | END LOOP;
FOR-LOOP
--------
В то время как число итераций цикла WHILE неизвестно до тех пор,
пока цикл не завершится, для цикла FOR число итераций известно
до того, как войти в цикл. Циклы FOR осуществляют свои итерации
по заданному интервалу целых чисел. (Курсорные циклы FOR,
которые повторяются по активному множеству курсора, обсуждаются
в главе 4.) Этот интервал является частью СХЕМЫ ИТЕРАЦИЙ,
которая окружается ключевыми словами FOR и LOOP. Синтаксис
имеет следующий вид:
FOR счетчик IN [REVERSE] нижняя_граница..верхняя_граница LOOP
ряд_предложений;
END LOOP;
Интервал вычисляется один раз, при первом входе в цикл, и больше
не перевычисляется. Как показывает следующий пример,
последовательность предложений выполняется один раз для каждого
целого в заданном интервале. После каждой итерации выполняется
приращение индекса цикла.
FOR i IN 1..3 LOOP -- присваивает переменной i значения 1, 2, 3
ряд_предложений; -- будет выполнен три раза
END LOOP;
Управляющие структуры 3-9
Как показывает следующий пример, если нижняя граница интервала
совпадает с верхней, цикл выполняется один раз:
FOR i IN 3..3 LOOP -- присваивает переменной i значение 3
ряд_предложений; -- будет выполнен один раз
END LOOP;
По умолчанию индекс наращивается на 1 от нижней до верхней
границы. Однако, если вы используете ключевое слово REVERSE,
индекс будет изменяться в обратном направлении, от верхней
границы к нижней, как показывает следующий пример. После каждой
итерации индекс уменьшается на 1.
FOR i IN REVERSE 1..3 LOOP -- присваивает переменной i 3, 2, 1
ряд_предложений; -- будет выполнен три раза
END LOOP;
Тем не менее, и в этом случае вы записываете границы интервала в
возрастающем (а не убывающем) порядке.
Внутри цикла FOR к индексу цикла можно обращаться как к
константе. Поэтому индекс может встречаться в выражениях, но
ему нельзя присваивать значений, как показывает следующий
пример:
FOR ctr IN 1..10 LOOP
...
IF NOT finished THEN
INSERT INTO ... VALUES (ctr, ...); -- законно
factor := ctr * 2; -- законно
...
ELSE
ctr := 10; -- незаконно
END IF;
END LOOP;
3-10 Руководство пользователя и справочник по PL/SQL
Схемы итераций
Границами интервала цикла могут быть литералы, переменные или
выражения, но их значения должны быть целочисленными. Например,
следующие схемы итераций законны:
j IN -5..5
k IN REVERSE first..last
step IN 0..TRUNC(high/low) * 2
code IN ASCII('A')..ASCII('J')
Как видите, нижняя граница не обязана быть равна 1. Однако
приращение (или отрицательное приращение) счетчика цикла всегда
равно 1. В некоторых языках существует фраза, с помощью которой
можно задать другую величину приращения. Пример на языке BASIC:
FOR J = 5 to 15 STEP 5 :REM присваивает J значения 5,10,15
ряд_предложений -- J имеет значения 5,10,15
NEXT J
В PL/SQL такой структуры не существует, но вы можете легко
смоделировать ее. Рассмотрим следующий пример:
FOR j IN 5..15 LOOP -- присваивает j значения 5,6,7,...
IF MOD(j, 5) = 0 THEN -- выбирает кратные 5
ряд_предложений; -- j имеет значения 5,10,15
END IF;
END LOOP;
Этот цикл логически эквивалентен предыдущему циклу BASIC.
Внутри поседовательности предложений счетчик цикла будет иметь
лишь значения 5, 10 и 15.
Вы можете предпочесть не столь элегантный, но более эффективный
способ, показанный в следующем примере. Внутри
последовательности предложений при каждом обращении к счетчику
цикла его значение умножается на 5.
FOR j IN 1..3 LOOP -- присваивает j значения 1,2,3
ряд_предложений; -- вместо j обращаться к j*5
END LOOP;
Динамические интервалы
PL/SQL позволяет определять интервал цикла динамически во время
выполнения, как показывает следующий пример:
SELECT COUNT(empno) INTO emp_count FROM emp;
FOR i IN 1..emp_count LOOP
...
END LOOP;
Значение emp_count неизвестно во время компиляции; предложение
SELECT возвращает это значение во время выполнения.
Управляющие структуры 3-11
Что произойдет, если вычисленная нижняя граница интервала
окажется больше верхней? Как показывает следующий пример,
последовательность предложений внутри цикла не будет
выполняться, и управление будет передано на следующее за циклом
предложение:
-- limit получает значение 1
FOR i IN 2..limit LOOP
ряд_предложений; -- не выполнится ни разу
END LOOP;
-- управление будет передано сюда
Правила сферы
Счетчик цикла определен только внутри цикла. Вы не можете
обратиться к нему вне цикла. После выхода из цикла значение
счетчика цикла не определено, как показывает следующий пример:
FOR ctr IN 1..10 LOOP
...
END LOOP;
sum := ctr - 1; -- незаконно
Вы не обязаны явно объявлять счетчик цикла, потому что он неявно
объявляется как локальная переменная типа INTEGER. Как
показывает следующий пример, это локальное объявление
перекрывает любое глобальное объявление:
DECLARE
ctr INTEGER;
BEGIN
...
FOR ctr IN 1..25 LOOP
...
IF ctr > 10 THEN ... -- обращается к счетчику цикла
END LOOP;
END;
Чтобы в этом примере обратиться к глобальной переменной ctr, вы
должны использовать метку и квалифицированную ссылку:
<>
DECLARE
ctr INTEGER;
BEGIN
...
FOR ctr IN 1..25 LOOP
...
IF main.ctr > 10 THEN ... --обращается к глоб.переменной
END LOOP;
END main;
3-12 Руководство пользователя и справочник по PL/SQL
Такие же правила сферы применимы к вложенным циклам FOR.
Рассмотрим следующий пример. Оба счетчика циклов имеют одно и
то же имя. Поэтому для того, чтобы обратиться из внутреннего
цикла к счетчику внешнего цикла, вы должны использовать метку и
квалифицированную ссылку:
<>
FOR step IN 1..25 LOOP
FOR step IN 1..10 LOOP
...
IF outer.step > 15 THEN ...
END LOOP;
END LOOP outer;
Использование предложения EXIT
Предложение EXIT позволяет завершить цикл FOR прежде времени.
Например, следующий цикл нормально выполняется десять раз, но,
как только предложение FETCH не сможет вернуть очередную строку,
цикл будет завершен независимо от того, сколько раз он успел
выполниться.
FOT j IN 1..10 LOOP
FETCH c1 INTO emp_rec;
EXIT WHEN c1%NOTFOUND;
...
END LOOP;
Предложение EXIT позволяет выйти не только из текущего цикла
FOR, но из любого окружающего цикла. Просто дайте метку тому
циклу, который вы хотите завершить, а затем укажите эту метку в
предложении EXIT:
<>
FOR i IN 1..5 LOOP
...
FOR j IN 1..10 LOOP
FETCH c1 INTO emp_rec;
EXIT outer WHEN c1%NOTFOUND; -- выход из обоих циклов
...
END LOOP;
END LOOP outer;
-- управление будет передано сюда
Управляющие структуры 3-13
----------------
Последовательное управление: предложения GOTO и NULL
В отличие от предложений IF и LOOP, предложения GOTO и NULL не
являются ключевыми в программировании на языке PL/SQL.
Структура языка такова, что предложение GOTO требуется редко.
Иногда его применение может быть оправдано некоторым упрощением
логики. Предложение NULL может прояснить смысл условных
предложений в программе и улучшить читабельность.
Предложение GOTO
----------------
Предложение GOTO выполняет безусловный переход к указанной
метке. Метка должна быть уникальной в своей сфере, и должна
предшествовать выполнимому предложению или блоку PL/SQL.
Предложение GOTO передает управление на помеченное предложение
или блок. В следующем примере управление передается на
выполнимое предложение, находящееся дальше в последовательности
предложений:
BEGIN
...
GOTO insert_row;
...
<>
INSERT INTO emp VALUES ...
END;
В следующем примере управление передается на блок PL/SQL,
расположенный выше в последовательности предложений:
BEGIN
...
<>
BEGIN
UPDATE emp SET ...
...
END;
...
GOTO update_row;
...
END;
3-14 Руководство пользователя и справочник по PL/SQL
В следующем примере метка <> незаконна, потому что она
стоит не перед выполнимым предложением:
DECLARE
done BOOLEAN;
BEGIN
...
FOR i IN 1..50 LOOP
IF done THEN
GOTO end_loop;
END IF;
...
<> -- незаконно
END LOOP; -- это не выполняемое предложение
END;
Чтобы исправить последний пример, просто добавьте за меткой
предложение NULL:
DECLARE
done BOOLEAN;
BEGIN
...
FOR i IN 1..50 LOOP
IF done THEN
GOTO end_loop;
END IF;
...
<>
NULL; -- выполняемое предложение
END LOOP;
END;
Как показывает следующий пример, предложение GOTO может передать
управление в окружающий блок из текущего блока:
DECLARE
my_ename CHAR(10);
BEGIN
...
<>
SELECT ename INTO my_ename FROM emp WHERE ...
...
BEGIN
...
GOTO get_name; -- переход в окружающий блок
END;
END;
Предложение GOTO передает управление в первый из окружающих
блоков, в котором встретится указанная метка.
Управляющие структуры 3-15
Ограничения
Некоторые возможные назначения предложения GOTO незаконны. В
частности, предложение GOTO не может передавать управление в
предложение IF, в предложение LOOP или в подблок. Например,
следующее предложение GOTO незаконно:
BEGIN
...
GOTO update_row; -- незаконный переход в предложение IF
...
IF valid THEN
...
<>
UPDATE emp SET ...
END IF;
END;
Далее, предложение GOTO не может передавать управление из одной
фразы предложения IF в другую, как показывает следующий пример:
BEGIN
...
IF valid THEN
...
GOTO update_row; -- незаконный переход в фразу ELSE
ELSE
...
<>
UPDATE emp SET ...
END IF;
END;
Следующий пример показывает, что предложение IF не может
передавать управление из окружающего блока в подблок:
BEGIN
...
IF status = 'OBSOLETE' THEN
GOTO delete_part; -- незаконный переход в подблок
END IF;
...
BEGIN
...
<>
DELETE FROM parts WHERE ...
END;
END;
3-16 Руководство пользователя и справочник по PL/SQL
Кроме того, предложение GOTO не может передавать управление
наружу из подпрограммы, как показывает следующий пример:
DECLARE
...
PROCEDURE compute_bonus (emp_id NUMBER) IS
BEGIN
...
GOTO update_row; -- незаконный переход из подпрограммы
END;
BEGIN
...
<>
UPDATE emp SET ...
END;
Наконец, предложение GOTO не может передавать управление из
обработчика исключений в текущий блок. Например, следующее
предложение GOTO незаконно:
DECLARE
...
pe_ratio REAL;
BEGIN
...
SELECT price / NVL(earnings, 0) INTO pe_ratioo FROM ...
<>
INSERT INTO stats VALUES (pe_ratio, ...);
EXCEPTION
WHEN ZERO_DIVIDE THEN
pe_ratio := 0;
GOTO insert_row; -- незаконный переход в текущий блок
...
END;
Однако предложение GOTO может передавать управление из
обработчика исключений в окружающий блок.
Советы
Чрезмерное применение предложений GOTO может привести к
сложному, неструктурированному коду, который трудно понимать и
сопровождать. Поэтому старайтесь использовать предложения GOTO
пореже. Например, чтобы перейти из глубоко вложенной структуры
на программу обработки ошибок, возбуждайте исключение, вместо
того чтобы использовать предложение GOTO.
Управляющие структуры 3-17
Предложение NULL
----------------
Предложение NULL явно специфицирует отсутствие действия; оно
ничего не делает, и управление передается на следующее
предложение. Оно, однако, может улучшить читабельность
программы. В конструкте, допускающем альтернативные действия,
предложение NULL используется для обозначения места действия.
Оно напоминает читателю программы о том, что соответствующая
альтернатива не была пропущена нечаянно, а просто не требует
никакого действия. В следующем примере предложение NULL
показывает, что для непоименованных исключений никакие действия
не выполняются:
...
EXCEPTION
WHEN ZERO_DIVIDE THEN
ROLLBACK;
WHEN CALUE_ERROR THEN
INSERT INTO errors VALUES ...
COMMIT;
WHEN OTHERS THEN
NULL;
END;
Каждая фраза в предложении IF должны содержать хотя бы одно
выполнимое предложение. Предложение NULL помогает удовлетворить
этому требованию. Поэтому вы можете использовать предложение
NULL в фразах, соответствующих тем обстоятельствам, в которых
никакий действий не требуется. В следующем примере предложение
NULL подчеркивает, что премии получат лишь сотрудники с высоким
рейтингом:
IF rating > 90 THEN
compute_bonus(emp_id);
ELSE
NULL;
END IF;
Предложение NULL предоставляет также удобный способ создания
"затычек" при разработке приложения сверху вниз. Затычки - это
фиктивные подпрограммы, с помощью которых вы откладываете
определения процедур и функций до тех пор, пока не проверите и
не отладите главную программу. В следующем примере предложение
NULL помогает удовлетворить тому требованию языка, что
выполнимая часть подпрограммы должна содержать хотя бы одно
предложение:
PROCEDURE debit_account (acct_id INTEGER, amount REAL) IS
BEGIN
NULL;
END debit_account;