PL/SQL 变量作用域与内外块:嵌套结构
什么是嵌套块 Oracle?
在 PL/SQL 中,每个块都可以嵌套到另一个块中。它们被称为嵌套块。当我们想要执行特定过程,同时又希望这些过程的代码保存在一个单独的容器(块)中时,嵌套块非常常见。
嵌套块概念通过将复杂的事情分解到每个块中,并允许在主外部块内的每个块中处理异常,从而帮助程序员提高可读性。
嵌套块结构
一个块可以嵌套到另一个块中。这可以嵌套在执行部分或异常处理部分。这些块也可以被标记。一个外部块可以包含多个内部块。每个内部块又是一个PL/SQL 块,因此内部块的所有属性和特征与外部块相同。下图是嵌套块结构的图示。父块是主块,子块是嵌套块。
以下是嵌套块的语法。
嵌套块语法
<<outer_block>> DECLARE <Declarative section> BEGIN <Execution part for outer block begins> <<inner block>> DECLARE <Declarative section> BEGIN <Execution part for inner block>. EXCEPTION <Exception handling part> END; <Execution part for outer block begins> EXCEPTION <Exception handling part> END;
- 上面的语法显示了包含总共两个块的嵌套块。
- 这些块被标记为“outer_block”和“inner_block”。
嵌套块中的作用域:变量作用域
在嵌套块中,在使用之前需要清楚地理解每个块的作用域和可见性。尤其是在内部块中,外部块和内部块的元素都可见,因此对这点的正确理解是必要的。
以下几点将更全面地总结嵌套块中的作用域。
- 在外部块中声明的元素以及在内部块定义之前定义的值在内部块中是可见的。
- 在内部块中声明的元素在外部块中不可见。它们仅在内部块内可见。
- 外部块和内部块可以拥有同名的变量。
- 对于同名变量,内部块默认只引用内部块中声明的变量。
- 如果内部块想要引用与内部块同名的外部块变量,那么外部块应该被标记,并且外部块变量可以被引用为“<outer_block_label>.<variable_name>”。
下面的示例将帮助您更深入地理解这些作用域。
示例 1:在此示例中,我们将查看内部块和外部块中变量的作用域。此外,我们还将学习如何使用块标签引用变量。
<<OUTER_BLOC>> DECLARE varl VARCHAR2(30):='outer_block'; var2 VARCHAR2(30):='value before inner block’; BEGIN <<NNER_BLOCK>> DECLARE varl VARCHAR2(30):='inner_block'; BEGIN dbms_output.put_line(varl), dbms_output.put_line(OUTER_BLOCKvar1); dbms_output.put_line(var2); END; var2:='value after inner block'; END; /
代码解释
- 代码行 1:将外部块标记为“OUTER_BLOCK”。
- 代码行 3:声明一个 VARCHAR2 (30) 类型的变量 'var1',初始值为“outer block”。
- 代码行 4:声明一个 VARCHAR2 (30) 类型的变量 'var2',初始值为“value before inner block”。
- 代码行 6:将内部块标记为“INNER_BLOCK”。
- 代码行 8:在内部块中声明一个 VARCHAR2 (30) 类型的变量 'var1',初始值为“inner block”。
- 代码行 10:打印 'var1' 的值。由于未指定标签,它将默认从内部块获取值,因此打印“inner_block”消息。
- 代码行 11:打印外部块变量 'var1' 的值。由于内部块中存在同名变量,我们需要引用外部块标签。因此打印“outer block”消息。
- 代码行 12:打印外部块变量 'var2' 的值。由于内部块中不存在此名称的变量,它将默认从外部块获取值,因此打印“value before inner block”消息。
- 外部块中的变量 'var2' 已被赋值为“value after inner block”。但此赋值发生在内部块定义之后。因此,此值在内部块中不存在。
示例 2:在此示例中,我们将找出两个数字的差值,一个在外部块中声明,另一个在内部块中声明。它们将具有相同的名称。让我们看看块标签在引用这些变量时有多么有用。
<<OUTER_BLOC>> DECLARE ln_val NUMBER :=5; BEGIN <<INNERBLOC>> DECLARE ln_val NUMBER :=3; BEGIN dbms_output.put_line(The difference between outer block and inner block variable is:'||' outer_block. ln_val-inner_block.ln_val); END; END; /
代码解释
- 代码行 1:将外部块标记为“OUTER_BLOCK”。
- 代码行 3:声明一个 NUMBER 类型的变量 'ln_val',初始值为“5”。
- 代码行 5:将内部块标记为“INNER_BLOCK”。
- 代码行 7:在内部块中声明一个 NUMBER 类型的变量 'ln_val',初始值为“3”。
- 代码行 9:打印 'ln_val' 在外部和内部块中的差值。“<block_name>.<variable_name>”格式用于引用这些变量,以避免因变量名相同而产生的冲突。
摘要
在本教程中,我们学习了如何创建嵌套块以及如何处理内部块和外部块中的作用域。我们还看到了一个内部块和外部块中的变量在内部块中被引用的示例。