Шаг 43 - PL/SQL - оператор IF - THEN - ELSE

Итак, попробуем использовать операторы ветвления. Самым простым в использовании, в PL/SQL является оператор IF. Его основная логическая форма имеет вид:

IF(некоторое условие справедливо) THEN
-- условие справедливо, выполнять это.
ELSE	-- условие не выполняется
-- выполнять оператор в этой части.
END IF;	-- конец условного оператора.

Первый блок оператора после IF-THEN называется "ПРЕДЫДУЩИМ", а блок следующий за ELSE "ПОСЛЕДУЮЩИМ". Каждый оператор IF-THEN может содержать обрамляющие блоки BEGIN - END, если в этом есть необходимость, так как при записи типа:

IF(некоторое условие справедливо) THEN
	-- оператор 1
	-- оператор 2
	-- оператор 3
	-- оператор 4
END IF;	-- конец условного оператора.

Можно уверенно сказать, что все четыре оператора выполнятся наверняка! Но, если применить такую конструкцию:

IF(некоторое условие справедливо) THEN
	BEGIN		
		-- оператор 1
		-- оператор 2
		-- оператор 3
		-- оператор 4
	END;						
END IF;	-- конец условного оператора.

Код будет более нагляден, хотя это вопрос относится к стилю программирования. Так же считается, хорошим стилем наличие комментария при использовании оператора IF. Особенно в случае большого количества вложений. Оператор IF можно вкладывать на любую глубину выражения. Таким образом, можно задать достаточно сложную логику выражения. Так же для экономии памяти, возможно использовать конструкцию, типа:

IF(некоторое условие справедливо) THEN	-- проверка условия
	BEGIN
		--   условие справедливо, выполнять это.
		.
		.
	END;	  
ELSE	-- условие не выполняется
	DECLARE 
		x NUMBER;
	BEGIN
		.
		.
	END;			 
END IF;	-- конец условного оператора.

В этом случае переменная x будет создана, если условие предыдущего блока ложно. Хотя использовать, такие конструкции не всегда оправдано. Так же условные операторы в PL/SQL вычисляются с помощью так называемой "сокращенной" оценки. Допустим, есть такое условие:

IF( a AND b ) THEN	-- проверка условия
	BEGIN
		.
		.
	END;	  
END IF;	-- конец условного оператора.

Если выражение a равно FALSE, то дальнейшее выражение не вычисляется! Все выражения вычисляются слева направо, а выражения в скобках, имеют наивысший приоритет. Например, вот так:

IF( (a OR f) AND (c OR k) ) THEN	-- проверка условия
	BEGIN
		.
		.
	END;	  
END IF;	-- конец условного оператора.

Выражения в скобках вычисляются первыми. Что ж, пришло время вспомнить старого знакомого! Работа с NULL. Оператор IF работает с NULL достаточно просто и эффективно. Если записать:

IF(X = NULL) THEN	-- проверка условия
	.
	.
END IF;	-- конец условного оператора.

IF(X != NULL) THEN	-- проверка условия
	.
	.
END IF;	-- конец условного оператора.

Такое условие будет иметь значение FALSE и ничего выполняться не будет. Правильная запись будет такая:

IF(X IS NULL) THEN	-- проверка условия
	.
	.
END IF;	-- конец условного оператора.

IF(X IS NOT NULL) THEN	-- проверка условия
	.
	.
END IF;	-- конец условного оператора.

От троичной логики никуда не деться, по этому запоминайте хорошенько! :) А, что делать, если необходимо проверить одно значение несколько раз? Например, вот так:

IF( val = 1 ) THEN	-- проверка условия
	.
	.
END IF;	-- конец условного оператора.

.
.
.

IF( val = 9 ) THEN	-- проверка условия
	.
	.
END IF;	-- конец условного оператора.

Такое количество операторов IF конечно можно использовать, но это слишком громоздко и не верно, так как существует конструкция IF - THEN - ELSIF. работает она достаточно просто и ее для таких целей по моему опыту вполне достаточно:

IF ( val = 1 ) THEN	-- проверка условия
	.
	.
ELSIF ( val = 2 ) THEN  
	.
	.
ELSIF ( val = 3 ) THEN  
	.
	.
ELSIF ( val = 9 ) THEN  
	.
	.
ELSE	-- не сработало не одно из условий!

END IF;	-- конец условного оператора.

Вот так это выглядит, достаточно просто и наглядно. Очень похоже на оператор CASE в языке Pascal. Но не совсем, хотя выполняет ту же функцию. Секция ELSE срабатывает, если не выполнилось ни одно из условий. Таким образом работает этот оператор. Как видите, на первый взгляд, все достаточно просто, хотя и реализует всю функциональность самого языка. Данный оператор является первым фундаментальным оператором языка PL/SQL. Что ж теперь, давайте изобразим небольшую программу для закрепления. Запускайте SQL*Plus и в любом редакторе наберите следующее:

-- OPER VARCHAR2(5) := '&TODO';

SET SERVEROUTPUT ON

DECLARE

A INTEGER := 7;
B INTEGER := 4;
OPER VARCHAR2(2) := '+';

BEGIN 	
	
	DBMS_OUTPUT.enable;
	IF (OPER = '+') THEN
	DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'sum = '||TO_CHAR(A+B));		
	ELSIF (OPER = '-') THEN
	DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'res = '||TO_CHAR(A-B));		
	ELSIF (OPER = '*') THEN
	DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'mul = '||TO_CHAR(A*B));		
	ELSIF (OPER = '/') THEN
	DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'div = '||TO_CHAR(A/B));		
	END IF; 
	
END;
/

После запуска получаем:

SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  2  
  3  A INTEGER := 7;
  4  B INTEGER := 4;
  5  OPER VARCHAR2(2) := '+';
  6  
  7  BEGIN
  8  
  9   DBMS_OUTPUT.enable;
 10   IF (OPER = '+') THEN
 11   DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'sum = '||TO_CHAR(A+B));
 12   ELSIF (OPER = '-') THEN
 13   DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'res = '||TO_CHAR(A-B));
 14   ELSIF (OPER = '*') THEN
 15   DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'mul = '||TO_CHAR(A*B));
 16   ELSIF (OPER = '/') THEN
 17   DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'div = '||TO_CHAR(A/B));
 18   END IF;
 19  
 20  END;
 21  /
Operation is + sum = 11                                                                             

Процедура PL/SQL успешно завершена.

В данном случае я применил конструкцию IF - THEN - ELSIF для создания чего-то похожего на калькулятор. В операторе DBMS_OUTPUT.put_line - для сцепления строк применяем конструкцию конкатенации строк вида "||" в результате вот такого выражения ('Operation is '||OPER||' '||'sum = '||TO_CHAR(A+B)) мы получаем строку "Operation is + sum = 11". Таким образом, происходит сцепление отдельных строковых литералов. Ее мы еще не раз применим в дальнейшем. В проверках условий в операторах IF - THEN - ELSIF хорошо видно, что производится сравнение переменной со строковым литералом, такие конструкции так же применимы при осуществлении проверок. Давайте немного усложним код программы, заменив выражение OPER VARCHAR2(2) := '+'; на OPER VARCHAR2(5) := '&TODO'; вот так:

SET SERVEROUTPUT ON

DECLARE

A INTEGER := 7;
B INTEGER := 4;
OPER VARCHAR2(5) := '&TODO';

BEGIN 	
	
	DBMS_OUTPUT.enable;
	IF (OPER = '+') THEN
	DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'sum = '||TO_CHAR(A+B));		
	ELSIF (OPER = '-') THEN
	DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'res = '||TO_CHAR(A-B));		
	ELSIF (OPER = '*') THEN
	DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'mul = '||TO_CHAR(A*B));		
	ELSIF (OPER = '/') THEN
	DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'div = '||TO_CHAR(A/B));		
	END IF; 
	
END;
/

После запуска увидите следующее:

SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  2  
  3  A INTEGER := 7;
  4  B INTEGER := 4;
  5  OPER VARCHAR2(5) := '&TODO';
  6  
  7  BEGIN
  8  
  9   DBMS_OUTPUT.enable;
 10   IF (OPER = '+') THEN
 11   DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'sum = '||TO_CHAR(A+B));
 12   ELSIF (OPER = '-') THEN
 13   DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'res = '||TO_CHAR(A-B));
 14   ELSIF (OPER = '*') THEN
 15   DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'mul = '||TO_CHAR(A*B));
 16   ELSIF (OPER = '/') THEN
 17   DBMS_OUTPUT.put_line('Operation is '||OPER||' '||'div = '||TO_CHAR(A/B));
 18   END IF;
 19  
 20  END;
 21  /

Введите значение для todo: * 

После запуска введите одну из типов операции +, -, *, / !!! А, затем увидите следующее, если введете скажем *:

прежний   5: OPER VARCHAR2(5) := '&TODO';
новый   5: OPER VARCHAR2(5) := '*';

Operation is * mul = 28                                                                             
Процедура PL/SQL успешно завершена.

Вот теперь наш калькулятор стал задавать нам вопросы, а виноват в этом литерал &, он трактуется SQL*Plus, как ждать ввода связанной переменной с именем "todo"! В данном случае "todo", есть так называемая "связанная" переменная. Вот так, просто и без затей. А вам домашнее задание переписать код для ввода, сначала чисел, а затем операции над ними! И запомнить, как работает оператор ветвлений в PL/SQL. Дерзайте!!!


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Летучий Сергей.