Команды IF в PL/SQL Oracle
Команда IF существует в трех формах: IF THEN END IF, IF THEN ELSE END IF и IF THEN ELSIF ELSE END IF.
Комбинация IF-THEN
Общий синтаксис конструкции IF-THEN выглядит так:
IF условие THEN ... последовательность исполняемых команд ... END IF;
Здесь условие — это логическая переменная, константа или логическое выражение с результатом TRUE, FALSE или NULL. Исполняемые команды между ключевыми словами THEN и END IF выполняются, если результат проверки условия равен TRUE, и не выполняются — если он равен FALSE или NULL.
Следующая условная команда IF сравнивает два числовых значения. Учтите, что если одно из них равно NULL, то и результат всего выражения равен NULL (если переменная salary равна NULL, то give_bonus не выполняется):
IF salary > 40000 THEN give_bonus (employee_id,500); END IF;
У правила, согласно которому NULL в логическом выражении дает результат NULL, имеются исключения. Некоторые операторы и функции специально реализованы так, чтобы при работе с NULL они давали результаты TRUE и FALSE (но не NULL). Например, для проверки значения NULL можно воспользоваться конструкцией IS NULL:
IF salary > 40000 OR salary IS NULL THEN give_bonus (employee_id,500); END IF;
В этом примере условие salary IS NULL дает результат TRUE, если salary не содержит значения, и результат FALSE во всех остальных случаях.
Для обнаружения возможных значений NULL и их обработки удобно применять такие операторы, как IS NULL и IS NOT NULL, или функции COALESCE и NVL2. Для каждой переменной в каждом написанном вами логическом выражении подумайте, что произойдет, если эта переменная содержит NULL.
Ключевые слова IF, THEN и END IF не обязательно размещать в отдельных строках. В командах IF разрывы строк не важны, поэтому приведенный выше пример можно было бы записать так:
IF salary > 40000 THEN give_bonus (employee_id,500); END IF;
Размещение всей команды в одной строке отлично подходит для простых конструкций IF — таких, как в приведенном примере. Но любая хоть сколько-нибудь сложная команда гораздо лучше читается, когда каждое ключевое слово размещается в отдельной строке. Например, если записать следующий фрагмент в одну строку, в нем будет довольно трудно разобраться. В нем нелегко разобраться даже тогда, когда он записан в три строки:
IF salary > 40000 THEN INSERT INTO employee_bonus (eb_employee_id, eb_bonus_amt) VALUES (employee_id, 500); UPDATE emp_employee SET emp_bonus_given=1 WHERE emp_ employee_id=employee_id; END IF;
И та же команда вполне нормально читается при разбиении на строки:
IF salary > 40000 THEN INSERT INTO employee_bonus (eb_employee_id, eb_bonus_amt) VALUES (employee_id, 500); UPDATE emp_employee SET emp_bonus_given=1 WHERE emp_employee_id=employee_id; END IF;
Вопрос удобочитаемости становится еще более важным при использовании ключевых слов ELSE и ELSIF, а также вложенных команд IF. Поэтому, чтобы сделать логику команд IF максимально наглядной, рекомендуется применять все возможности отступов и форматирования.
Конструкция IF-THEN-ELSE
Конструкция IF-THEN-ELSE применяется при выборе одного из двух взаимоисключающих действий. Формат этой версии команды IF:
IF условие THEN ... последовательность команд для результата TRUE ... ELSE ... последовательность команд для результата FALSE/NULL ... END IF;
Здесь условие — это логическая переменная, константа или логическое выражение. Если его значение равно TRUE, то выполняются команды, расположенные между ключевыми словами THEN и ELSE, а если FALSE или NULL — команды между ключевыми словами ELSE и END IF.
Важно помнить, что в конструкции IF-THEN-ELSE всегда выполняется одна из двух возможных последовательностей команд. После выполнения соответствующей последовательности управление передается команде, которая расположена сразу после ключевых слов END IF.
Следующая конструкция IF-THEN-ELSE расширяет пример IF-THEN, приведенный чуть-чуть выше:
IF salary <= 40000 THEN give_bonus (employee_id, 0); ELSE give_bonus (employee_id, 500); END IF;
В этом примере сотрудники с окладом более 40 000 получат премию в 500, а остальным премия не назначается. Или все же назначается? Что произойдет, если у сотрудника по какой-либо причине оклад окажется равным NULL? В этом случае будут выполнены команды, следующие за ключевым словом ELSE, и работник получит премию, положенную только высокооплачиваемому составу. Поскольку мы не можем быть уверены в том, что оклад ни при каких условиях не окажется равным NULL, нужно защититься от подобных проблем при помощи функции NVL:
IF NVL(salary,0) <= 40000 THEN give_bonus (employee_id, 0); ELSE give_bonus (employee_id, 500); END IF;
Функция NVL возвращает нуль, если переменная salary равна NULL. Это гарантирует, что работникам с окладом NULL будет начислена нулевая премия.
Конструкция IF-THEN-ELSIF
Данная форма команды IF удобна для реализации логики с несколькими альтернативными действиями в одной команде IF. Как правило, ELSIF используется с взаимоисключающими альтернативами (то есть при выполнении команды IF истинным может быть только одно из условий). Обобщенный синтаксис этой формы IF выглядит так:
IF условие-1 THEN команды-1 ELSIF condition-N THEN команды-N [ELSE команды_else] END IF;
Формально конструкция IF-THEN-ELSIF представляет собой один из способов реализации функций команды CASE в PL/SQL.
В каждой секции ELSIF (кроме секции ELSE) за условием должно следовать ключевое слово THEN. Секция ELSE в IF-ELSIF означает «если не выполняется ни одно из условий», то есть когда ни одно из условий не равно TRUE, выполняются команды, следующие за ELSE. Следует помнить, что секция ELSE не является обязательной — конструкция IF-ELSIF может состоять только из секций IF и ELSIF. Если ни одно из условий не равно TRUE, то никакие команды блока IF не выполняются.
Далее приводится полная реализация логики назначения премий, описанной чуть выше, на базе конструкции IF-THEN-ELSEIF:
IF salary BETWEEN 10000 AND 20000 THEN give_bonus(employee_id, 1500); ELSIF salary BETWEEN 20000 AND 40000 THEN give_bonus(employee_id, 1000); ELSIF salary > 40000 THEN give_bonus(employee_id, 500); ELSE give_bonus(employee_id, 0); END IF;