Oracle PL/SQL IF THEN ELSE 语句:ELSIF,嵌套 IF

什么是决策语句?

决策语句是根据条件决定控制流的SQL语句。它使程序员能够更好地控制阻止特定代码执行(图1)或根据条件选择所需代码(图2)。下面是“决策语句”的图示表示。

Decision Making Statement Diagram
决策语句图

决策语句的类型

Oracle 提供了以下类型的决策语句。

  • IF-THEN
  • IF-THEN-ELSE
  • IF-THEN-ELSIF
  • NESTED-IF
  • CASE
  • SEARCHED CASE

IF-THEN 语句

IF-THEN 语句主要用于仅在满足条件时执行特定代码段。

条件应返回布尔值(真/假)。它是一个基本的条件语句,允许 ORACLE 根据预定义条件执行/跳过特定代码块。

IF THEN 语句的语法

IF <condition: returns Boolean>
THEN
 -executed only if the condition returns TRUE 
 <action_block>
END if;
  • 在上述语法中,“IF”关键字后会跟一个评估为“TRUE”/“FALSE”的条件。
  • 仅当条件返回“TRUE”时,控制流才会执行<action_block>。
  • 如果条件评估为“FALSE”,则 SQL 将跳过<action_block>,并开始执行“END IF”块之后的代码。

注意:每当条件评估为“NULL”时,SQL 将“NULL”视为“FALSE”。

示例 1:在此示例中,当数字大于 100 时,我们将打印一条消息。为此,我们将执行以下代码

要打印一条消息,当一个数字的值大于 100 时,我们执行以下代码。

DECLARE 
a NUMBER :=10;
BEGIN
dbms_output.put_line(‘Program started.' );
IF( a > 100 ) THEN
dbms_output.put_line('a is greater than 100'); 
END IF;
dbms_output.put_line(‘Program completed.');
END;
/

代码解释

  • 代码行 2:将变量“a”声明为“NUMBER”数据类型,并将其初始化为值“10”。
  • 代码行 4:打印语句“程序已开始”。
  • 代码行 5:检查条件,变量“a”是否大于“100”。
  • 代码行 6:如果“a”大于“100”,则打印“a 大于 100”。如果“a”小于或等于 100,则条件失败,因此上述打印语句将被忽略。
  • 代码行 8:打印语句“程序已完成”。

代码输出

Program started.
Program completed.

示例 2:在此示例中,如果给定的字母是英语元音(A、E、I、O、U)之一,我们将打印一条消息。

要打印一条消息,当给定字符是元音时,我们执行以下代码。

DECLARE 
a CHAR(1) :=’u’;
BEGIN
IF UPPER(a) in ('A’,'E','I','0','U' ) THEN 
dbms_output.put_line(‘The character is in English Vowels');
END IF;
END;
/

代码解释

  • 代码行 2:将变量“a”声明为大小为“1”的“CHAR”数据类型,并将其初始化为值“u”。
  • 代码行 4:检查条件,变量“a”是否在列表(“A”、“E”、“I”、“O”、“U”)中。
  • 在比较之前,变量“a”的值已转换为大写,以使比较不区分大小写。
  • 代码行 5:如果“a”在列表中,则打印语句“该字符是英语元音”。如果条件失败,则此程序将不产生任何输出,因为在 IF-THEN 块之外,我们没有发出任何打印语句。

代码输出

The character is in English Vowels

IF-THEN-ELSE 语句

  • IF-THEN-ELSE 语句主要用于根据条件在两个备选方案之间进行选择。
  • 下面是 IF-THEN-ELSE 语句的语法表示。

IF-THEN-ELSE 语句的语法

IF <condition: returns Boolean>
THEN
	-executed only if the condition returns TRUE
	<action_blockl>
ELSE
	-execute if the condition failed (returns FALSE)
	<action_block2>
END if;
  • 在上述语法中,“IF”关键字后会跟一个评估为“TRUE”/“FALSE”的条件。
  • 仅当条件返回“TRUE”时,控制流才会执行<action_block1>。
  • 如果条件评估为“FALSE”,则 SQL 将执行<action_block2>。
  • 在任何情况下,两个操作块中的一个都将被执行。

注意:每当条件评估为“NULL”时,SQL 将“NULL”视为“FALSE”。

示例 1:在此示例中,我们将打印一条消息,说明给定的数字是奇数还是偶数。

DECLARE 
a NUMBER:=11;
BEGIN
dbms_output.put_line (‘Program started');
IF( mod(a,2)=0) THEN 
dbms_output.put_line('a is even number' ); 
ELSE
dbms_output.put_line('a is odd number1); 
END IF;
dbms_output.put_line (‘Program completed.’);
END;
/

代码解释

  • 代码行 2:将变量“a”声明为“NUMBER”数据类型,并将其初始化为值“11”。
  • 代码行 4:打印语句“程序已开始”。
  • 代码行 5:检查条件,变量“a”除以“2”的模是否为 0。
  • 代码行 6:如果为“0”,则打印“a 是偶数”。
  • 代码行 7:如果模值不等于“0”,则条件返回“FALSE”,因此打印“a 是奇数”的消息。
  • 代码行 10:打印语句“程序已完成”。

代码输出

Program started.
a is odd number
Program completed.

IF-THEN-ELSIF 语句

  • IF-THEN-ELSIF 语句主要用于从一组备选方案中选择一个,其中每个备选方案都有自己的条件需要满足。
  • 第一个返回“TRUE”的条件将被执行,其余条件将被跳过。
  • IF-THEN-ELSIF 语句可能包含“ELSE”块。如果没有任何条件得到满足,则执行此“ELSE”块。

注意:在此条件语句中,“ELSE”块是可选的。如果没有“ELSE”块,并且没有任何条件得到满足,那么控制器将跳过所有操作块并开始执行代码的其余部分。

IF-THEN-ELSIF 语句的语法

IF <conditionl: returns Boolean>
THEN
-executed only if the condition returns TRUE <
action_blockl>
ELSIF <condition2 returns Boolean> <
action_block2>
ELSIF <condition3:returns Boolean> <
action_block3>
ELSE —optional 
<action_block_else>
END if;
  • 在上述语法中,仅当 condition1 返回“TRUE”时,控制流才会执行<action_block1>。
  • 如果 condition1 不满足,则控制器将检查 condition2。
  • 控制器将在以下两种情况下退出 IF 语句。
    • 当控制器找到任何返回“TRUE”的条件时。在这种情况下,将执行相应的 action_block,并且控制器将退出此 IF 语句块并开始执行其余代码。
    • 当没有任何条件得到满足时,控制器将执行 ELSE 块(如果存在),然后退出 IF 语句。

注意:每当条件评估为“NULL”时,SQL 将“NULL”视为“FALSE”。

示例 1:不带 ELSE 块

在此示例中,我们将根据给定的分数打印等级,不带 else 条件(分数 >= 70 为 A 级,分数 >= 40 且 < 70 为 B 级,分数 >= 35 且 < 40 为 C 级)。

DECLARE
mark NUMBER :=55;
BEGIN
dbms_output.put_line(‘Program started.’ );
IF( mark >= 70) THEN 
dbms_output.put_line(‘Grade A’);
ELSIF(mark >= 40 AND mark < 70) THEN
dbms_output.put_line(‘Grade B'); 
ELSIF(mark >=35 AND mark < 40) THEN
dbms_output.put_line(‘Grade C’);
END IF;
dbms_output.put_line(‘Program completed.’); 
END;
/

代码解释

  • 代码行 2:将变量“mark”声明为“NUMBER”数据类型,并将其初始化为值“55”。
  • 代码行 4:打印语句“程序已开始”。
  • 代码行 5:检查 condition1,即“mark”是否大于或等于 70。
  • 代码行 7:由于 condition1 失败,因此检查 condition2“70 > mark >= 40”。
  • 代码行 8:condition2 返回“TRUE”,因此将打印消息“B 级”。
  • 代码行 12:打印语句“程序已完成”。
  • 在这种情况下,condition3“mark < 35”将被跳过,因为在 condition3 之前,控制器找到了一个返回“TRUE”的条件。

代码输出

Program started.
Grade B
Program completed.

示例 2:带 ELSE 块

在此示例中,我们将根据给定的分数打印等级,带 else 条件(分数 >= 70 为 A 级,分数 >= 40 且 < 70 为 B 级,分数 >= 35 且 < 40 为 C 级,否则为“无等级”)。

DECLARE
mark NUMBER :=25;
BEGIN
dbms_output.put_line(‘Program started.’ );
IF( mark >= 70) THEN 
dbms_output.put_line(‘Grade A’); 
ELSIF(mark >= 40 AND mark < 70) THEN 
dbms_output.put_line(‘Grade B'); 
ELSIF(mark >=35 AND mark < 40) THEN 
dbms_output.put_line(‘Grade C);
ELSE
dbms_output.put_line(‘No Grade’);
END IF;
dbms_output.put_line(‘Program completed.' ); 
END;
/

代码解释

  • 代码行 2:将变量“mark”声明为“NUMBER”数据类型,并将其初始化为值“25”。
  • 代码行 4:打印语句“程序已开始”。
  • 代码行 5:检查 condition 1,即“mark”是否大于或等于 70。
  • 代码行 7:由于 condition1 失败,因此检查 condition2“70 > mark >= 40”。
  • 代码行 8:由于 condition2 失败,因此检查 condition3“40 > mark >= 35”。
  • 代码行 11:由于所有条件都失败了,控制流现在将检查 ELSE 块是否存在,并将从 ELSE 块打印消息“无等级”。
  • 代码行 14:打印语句“程序已完成”。

代码输出

Program started.
No Grade 
Program completed.

嵌套 IF 语句

  • NESTED-IF 语句基本上允许程序员将一个或多个“IF”条件放置在另一个“IF”条件的<action_block>中,而不是常规语句。
  • 每个“IF”条件都应该有一个单独的“END IF”语句,该语句标记该特定<action_block>的范围结束。
  • “IF”语句会将最近的“END IF”语句视为该特定条件的终结点。
  • 下面图示显示了 NESTED-IF 的图示表示。

NESTED-IF Statement

NESTED-IF Statement

IF <conditionl: returns Boolean>
THEN
	—executed only if the condition returns TRUE
	<action block1 starts>
	IF <condition2: returns Boolean>
	THEN
	<action_block2>
	END IF; —END IF corresponds to condition2
<action_blockl ends>
END IF; —END IF corresponds to condition1

语法说明

  • 在上述语法中,外部 IF 的操作块中包含另一个 IF 语句。
  • 如果 condition1 返回“TRUE”,则控制流将执行<action_block1>并检查 condition2。
  • 如果 condition2 也返回“TRUE”,则也将执行<action_block2>。
  • 如果 condition2 评估为“FALSE”,则 SQL 将跳过<action_block2>。

这里我们将看到一个嵌套 IF 的例子 –

嵌套 IF 语句示例:三个数中的最大值

在此示例中,我们将使用嵌套 IF 语句打印三个数中的最大值。数字将在声明部分赋值,如您在下面的代码中所见,即 Number = 10、15 和 20,并且最大数字将使用嵌套 IF 语句获取。

DECLARE 
a NUMBER :=10; 
b NUMBER :=15; 
c NUMBER :=20;
BEGIN
dbms_output.put_line(‘Program started.' );
IF( a > b)THEN
/*Nested-if l */
	dbms_output.put_line(’Checking Nested-IF 1'); 
	IF( a > c ) THEN
	dbms_output.put_line(‘A is greatest’); 
	ELSE
	dbms_output.put_line(‘C is greatest’); 
	END IF;
ELSE
/*Nested-if2 */
	dbms_output.put_line('Checking Nested-IF 2' ); 
	IF( b > c ) THEN
	dbms_output.put_line(’B is greatest' ); 
	ELSE
	dbms_output.put_line(’C is greatest' ); 
	END IF;
END IF;
dbms_output.put_line(‘Program completed.’ );
END;
/

代码解释

  • 代码行 2:将变量“a”声明为“NUMBER”数据类型,并将其初始化为值“10”。
  • 代码行 3:将变量“b”声明为“NUMBER”数据类型,并将其初始化为值“15”。
  • 代码行 4:将变量“c”声明为“NUMBER”数据类型,并将其初始化为值“20”。
  • 代码行 6:打印语句“程序已开始”(第 6 行)。
  • 代码行 7:检查 condition1,即“a”是否大于“b”(第 7 行)。
  • 代码行 10:如果“a”大于“b”,则“nested-if 1”中的条件将检查“a”是否大于“c”(第 10 行)。
  • 代码行 13:如果“a”仍然更大,则打印消息“A 最大”(第 11 行)。否则,如果 condition2 失败,则打印“C 最大”(第 13 行)。
  • 代码行 18:如果 condition1 返回 false,则“nested-if 2”中的条件将检查“b”是否大于“c”(第 18 行)。
  • 代码行 21:如果“b”大于“c”,则打印消息“B 最大”(第 19 行),否则,如果 condition2 失败,则打印“C 最大”(第 21 行)。
  • 代码行 24:打印语句“程序已完成”(第 24 行)。

代码输出

Program started.
Checking Nested-IF 2
C is greatest
Program completed.

摘要

在本章中,我们学习了不同的决策语句及其语法和示例。下表总结了我们讨论过的各种条件语句。

类型 描述 用途
IF-THEN 检查布尔条件,如果为 TRUE,则执行“THEN”块中的代码。 根据条件跳过/执行特定代码。
IF-THEN-ELSE 检查布尔条件,如果为 TRUE,则执行“THEN”块中的代码,如果为 FALSE,则执行“ELSE”块中的代码。 最适用于“此或彼”条件。
IF-THEN-ELSIF 按顺序检查布尔条件。序列中第一个返回 TRUE 条件的代码将被执行。如果序列中没有任何条件为 TRUE,则执行“ELSE”块中的代码。 主要用于选择两个以上的备选方案。
NESTED-IF 允许在一个或多个 IF-THEN 或 IF-THEN-ELSIF 语句中包含一个或多个 IF-THEN 或 IF-THEN-ELSIF 语句。 主要用于嵌套条件情况。