Oracle PL/SQL Programming 第4章:Language Fundamentals 读书笔记

总的目录和进度,请参见开始读 Oracle PL/SQL Programming 第6版

本章介绍两种类型的 PL/SQL 控制语句:条件控制语句和顺序控制语句。 几乎您编写的每一段代码都需要条件控制,即根据条件指导程序执行流程的能力。 您可以使用 IF-THEN-ELSE 和 CASE 语句来执行此操作。 还有CASE表达式; 虽然与 CASE 语句不同,但它们有时可用于完全消除对 IF 或 CASE 语句的需要。 极少情况下,您需要告诉 PL/SQL 通过 GOTO 语句无条件转移控制,或者通过 NULL 语句显式地不执行任何操作。

IF Statements

IF 语句允许您在程序中实现条件分支逻辑。

IF 语句有三种形式,如下表所示。

IF 类型 特征
IF THEN
END IF;
这是 IF 语句的最简单形式。 IF 和 THEN 之间的条件决定是否执行 THEN 和 END IF 之间的语句集。 如果条件的计算结果为 FALSE 或 NULL,则不执行代码。
IF THEN
ELSE
END IF;
这种组合实现了非此即彼的逻辑:根据 IF 和 THEN 关键字之间的条件,执行 THEN 和 ELSE 之间或 ELSE 和 END IF 之间的代码。 执行这两部分可执行语句之一。
IF THEN
ELSIF
ELSE
END IF;
IF 语句的最后一种也是最复杂的形式从一系列互斥条件中选择一个为 TRUE 的条件,然后执行与该条件关联的语句集。 这种情况应该考虑使用搜索 CASE 语句。

The IF-THEN Combination

IF-THEN 语法的一般格式如下:

IF 条件
THEN
   ... 代码 ...
END IF;

条件为TRUE则执行代码,条件也可能为FALSE或NULL。

THREE-VALUED LOGIC

二值逻辑指布尔逻辑,即只提供真和假;三值逻辑除真假外,还提供一个不确定值,NULL,例如:

2 < NULL

要了解有关三值逻辑的更多信息,我推荐 Lex de Haan 和 Jonathan Gennick 的 Oracle 杂志文章“Nulls:Nothing to Worry About”。 您可能会发现 C. J. Date 的书《Database in Depth: Relational Theory for the Practitioner》也很有帮助。

使用 IS NULL 和 IS NOT NULL 等运算符或 COALESCE 和 NVL2 等函数是检测和处理潜在 NULL 值的好方法。 对于您编写的每个布尔表达式中引用的每个变量,请务必仔细考虑该变量为 NULL 时的后果。

格式方面,充分利用缩进和格式,使 IF 语句的逻辑易于理解。 未来的维护程序员会感谢你的。

The IF-THEN-ELSE Combination

当您想要在两个互斥的操作之间进行选择时,请使用 IF-THEN-ELSE 格式。

IF condition
THEN
   ... TRUE 可执行语句序列 ...
ELSE
   ... FALSE/NULL 可执行语句序列 ...
END IF;

需要记住的重要一点是,两个语句序列之一将始终执行,因为 IF-THEN-ELSE 是一个非此即彼的结构。

USING BOOLEAN FLAGS

通常,使用布尔变量作为标志很方便,这样您就不需要多次计算相同的布尔表达式。 执行此操作时,请记住布尔表达式的结果可以直接分配给布尔变量。

即,下面的语句:

IF 表达式
...

可以用以下替代,好处我理解是可以打印值,方便调试:

boolean_variable = 表达式;
IF boolean_variable 
...

The IF-THEN-ELSIF Combination

IF 条件1
THEN
   语句1
ELSIF 条件2
THEN
   语句2
[ELSE
   语句N]
END IF;

IF-THEN-ELSIF通常应该用CASE替代。注意ELSIF后面必须跟THEN,只有ELSE后面不需要THEN

Avoiding IF Syntax Gotchas

  • IF和END IF必须成对出现
  • END和IF间必须有空格
  • ELSIF 不要写成 ELSEIF
  • 只有END IF后面必须跟分号

IF-ELSIF中的条件,按顺序评估。如果有多个条件TRUE(应尽量避免),则先满足的会被执行,余下的不会评估。

Nested IF Statements

对于复杂的逻辑,嵌套IF通常是必要的,但要小心,因为其难以理解和调试。

嵌套IF的好处是,只有外层的IF为TRUE是,内层的IF才会评估。

Short-Circuit Evaluation

捷径评估是指不必评估IF语句中的所有表达式。例如逻辑AND和逻辑OR。

IF 条件1 AND 条件2
THEN
   ...
ELSE
   ...
END IF;

条件1为FALSE或NULL时,PL/SQL可以停止对表达式的求值,因为只有当表达式的结果为TRUE时才执行THEN分支,并且这需要两个操作数都为TRUE。一旦发现一个操作数不是TRUE,则不再有机会执行THEN分支。

注意,捷径评估仅适用于IF表达式,但对于赋值语句则不适用。
例如:

my_boolean := 条件1 AND 条件2

如果条件1为NULL,则仍会继续评估条件2。因为此时my_boolean 的值取决于条件2。若条件2为NULL,则my_boolean 为NULL,若条件2为FALSE,则my_boolean 为FALSE。

关于这点,详见文章Nulls: Nothing to Worry About中的图1。

捷径评估也适用于CASE语句和CASE表达式。

CASE Statements and Expressions

CASE语句包括简单CASE和搜索CASE两类。CASE语句外,还有CASE表达式。

在PL/SQL的范畴,前面布尔表达式的赋值可以有TRUE,FALSE和NULL。而放在关系型数据库的范畴,三值逻辑中只有TRUE,FASLE和UNKNOWN。例如SQL的WHERE条件和CHECK约束。NULL和UNKNOWN是不同的。

Simple CASE Statements

先评估expression,根据结果再判断执行哪一分支。

CASE expression
WHEN result1 THEN
   statements1
WHEN result2 THEN
   statements2
...
ELSE
   statements_else
END CASE;

ELSE部分是可选的。但你没有写ELSE时,PL/SQL会隐式替换为以下:

ELSE
   RAISE CASE_NOT_FOUND;

这和IF是不一样的,IF不会报错。

这里要注意的关键点是,前面的语法图中显示的表达式(expression)和结果元素(result*#n*)可以是标量值,也可以是计算结果为标量值的表达式。例如:

CASE TRUE
...
WHEN A > 200 AND ...

为了避免 CASE_NOT_FOUND 错误,请确保不会存在任何条件都不满足的情况。

Searched CASE Statements

搜索的 CASE 语句计算布尔表达式列表,当它找到计算结果为 TRUE 的表达式时,执行与该表达式关联的语句序列。

CASE
WHEN expression1 THEN
   statements1
WHEN expression2 THEN
   statements2
...
ELSE
   statements_else
END CASE;

与简单的 CASE 语句一样,适用以下规则:

  • 一旦执行了一系列语句,执行就会结束。 如果多个表达式的计算结果为 TRUE,则仅执行与第一个此类表达式关联的语句。
  • ELSE 子句是可选的。 如果未指定 ELSE,并且没有表达式计算结果为 TRUE,则会引发 CASE_NOT_FOUND 异常。
  • WHEN 子句按从上到下的顺序进行评估。

注意:由于 WHEN 子句是按顺序求值的,因此您可以通过首先列出最可能的 WHEN 子句来提高代码的效率。 此外,如果您的 WHEN 子句包含“昂贵”的表达式(例如,需要大量 CPU 和内存),您可能需要将它们列在最后,以尽量减少它们被评估的机会。

Nested CASE Statements

CASE 语句可以像 IF 语句一样嵌套。

CASE
WHEN ...
   CASE
   WHEN ...
	...
   END CASE;
...   
END CASE;

CASE Expressions

CASE 表达式对于表达式的作用与 CASE 语句对于语句的作用相同。 简单的 CASE 表达式允许您根据作为输入提供的标量值选择要计算的表达式。 搜索的 CASE 表达式对表达式列表进行计算,以找到第一个计算结果为 TRUE 的表达式,然后返回关联表达式的结果。

CASE 表达式有以下两种形式:

Simple_Case_Expression :=
   CASE expression
   WHEN result1 THEN
      result_expression1
   WHEN result2 THEN
      result_expression2
   ...
   ELSE
      result_expression_else
   END;
   
Searched_Case_Expression :=
   CASE
   WHEN expression1 THEN
      result_expression1
   WHEN expression2 THEN
      result_expression2
   ...
   ELSE
      result_expression_else
   END;

CASE 表达式返回单个值,即选择的 result_expression 的结果。 每个 WHEN 子句必须与一个表达式(无语句)关联。 不要使用分号或 END CASE 来标记 CASE 表达式的结束。 CASE 表达式由简单的 END 终止。

其实有点像look-up table。

与 CASE 语句不同,如果在 CASE 表达式中未选择 WHEN 子句,则不会引发错误。 相反,当不满足 WHEN 条件时,CASE 表达式将返回 NULL。

The GOTO Statement

GOTO 语句执行无条件分支到 PL/SQL 块的同一执行部分中的另一个可执行语句。 与该语言中的其他结构一样,如果您正确且谨慎地使用 GOTO,您的程序将会变得更加强大。

GOTO 语句的一般格式是:

GOTO 标签名称;

其中 label_name 是标识目标语句的标签名称。 这个GOTO标签在程序中定义如下:

<<标签名称>>

GOTO 语句有几个限制:

  • 标签后面必须至少有一条可执行语句。
  • 目标标签必须与 GOTO 语句位于同一范围内。
  • 目标标签必须与 GOTO 位于 PL/SQL 块的同一部分。

由于 PL/SQL 提供了如此多不同的控制结构和模块化技术,因此您几乎总能找到比 GOTO 更好的方法来完成某些任务。我不建议用。

The NULL Statement

在某些情况下,您希望 PL/SQL 不执行任何操作,此时 可用NULL 语句:

NULL;

NULL使用场景,包括:

  • 提高代码的可读性
  • 为调试,作为临时的占位符
  • 作为<<标签名称>>后面的语句,因为标签后面必须有语句

单词

  • decipherable 可破译的,好理解的

你可能感兴趣的:(Oracle,PL/SQL,Oracle数据库开发,oracle,sql,database,pl/sql,programming)