PostgreSQL – 块结构
PL/pgSQL 是一种块结构语言,因此,PL/pgSQL函数或存储过程被组织成块。
Syntax:
[ <
我们来分析一下上面的语法:
- 每个块有两个部分:声明和正文。声明部分是可选的,而正文部分是必需的。该块以END关键字后的分号 (;)结束。
- 一个块可能有一个位于开头和结尾的可选标签。如果您想在块体的EXIT语句中指定它,或者您想限定在块中声明的变量的名称,则可以使用块标签。
- 声明部分是您声明主体部分中使用的所有变量的地方。声明部分中的每个语句都以分号 (;) 结束。
- 正文部分是您放置代码的地方。正文部分中的每个语句也以分号结尾。
例子:
以下示例说明了一个非常简单的块,也称为匿名块。
DO $$
<>
DECLARE
counter integer := 0;
BEGIN
counter := counter + 1;
RAISE NOTICE 'The current value of counter is %', counter;
END first_block $$;
NOTICE: The current value of counter is 1
上面块的pgAdmin执行可以通过点击界面上的执行按钮来完成,如下图所示:
注意: DO语句不属于块。它用于执行匿名块。 PostgreSQL从 9.0 版本开始引入DO语句。
在声明部分,我们声明了一个变量counter并将其值设置为零。在正文部分,我们将计数器的值增加到 1 并使用RAISE NOTICE 语句输出其值。该first_block标签只是为了演示的目的。
双元($$)的概念:
双美元 ($$) 是单引号 (') 的替代。当您开发 PL/pgSQL 块、函数或存储过程时,您必须以字符串字面量的形式传递其主体。此外,您必须转义正文中的所有单引号 ('),如下所示:
DO
'<>
DECLARE
counter integer := 0;
BEGIN
counter := counter + 1;
RAISE NOTICE ''The current value of counter is %'', counter;
END first_block';
如果您使用双美元 ($$),您可以避免引用问题。您还可以在 $$ 之间使用令牌,例如 $函数$ 或$procedure$ 。
PL/pgSQL 子块:
PL/pgSQL 允许您将一个块放置在另一个块的主体内。这个嵌套在另一个块中的块称为子块。包含子块的块称为外部块。
子块用于对语句进行分组,以便将一个大块划分为更小且更具逻辑性的子块。子块中的变量的名称可以与外部块中的名称相同,尽管这不是一个好的做法。
当您在子块中声明一个与外部块中的变量同名的变量时,外部块中的变量将隐藏在子块中。如果要访问外部块中的变量,请使用块标签来限定其名称。
例子:
DO $$
<>
DECLARE
counter integer := 0;
BEGIN
counter := counter + 1;
RAISE NOTICE 'The current value of counter is %', counter;
DECLARE
counter integer := 0;
BEGIN
counter := counter + 10;
RAISE NOTICE 'The current value of counter in the subblock is %', counter;
RAISE NOTICE 'The current value of counter in the outer block is %', outer_block.counter;
END;
RAISE NOTICE 'The current value of counter in the outer block is %', counter;
END outer_block $$;
输出:
NOTICE: The current value of counter is 1
NOTICE: The current value of counter in the subblock is 10
NOTICE: The current value of counter in the outer block is 1
NOTICE: The current value of counter in the outer block is 1
我们来分析一下上面的例子:
- 首先,我们在outer_block 中声明了一个名为counter的变量。
- 然后,在进入子块之前,计数器的值为1。在子块中,我们将计数器的值增加到 10 并打印出来。请注意,更改仅影响子块中的计数器变量。
- 之后,我们使用块标签来引用外部块中的计数器变量来限定其名称outer_block.counter
- 最后,我们打印出外部块中计数器变量的值,其值保持不变。