PostgreSQL 教程: PL/pgSQL 变量

八月 19, 2023

摘要:在本教程中,您将学习声明 PL/pgSQL 变量的各种技术。

PL/pgSQL 变量简介

变量是内存位置的有意义的名称。变量保存可以通过代码块更改的值。变量总是会关联特定的数据类型

在使用变量之前,必须在 PL/pgSQL 代码块的声明部分中声明它。

下面说明了声明变量的语法。

variable_name data_type [:= expression];

在这个语法中:

  • 首先,指定变量的名称。为变量分配一个有意义的名称是一个很好的做法。例如,您应该使用indexcounter来命名变量,而不是i
  • 其次,将特定数据类型与变量相关联。数据类型可以是任何有效的数据类型,例如 integernumericvarcharchar
  • 第三,可以选择为变量分配默认值。如果不这样做,变量的初始值为NULL

请注意,您可以使用:==赋值运算符来初始化变量并向变量赋值。

以下示例说明了如何声明和初始化变量:

do $$ 
declare
   counter    integer := 1;
   first_name varchar(50) := 'John';
   last_name  varchar(50) := 'Doe';
   payment    numeric(11,2) := 20.5;
begin 
   raise notice '% % % has been paid % USD', 
       counter, 
	   first_name, 
	   last_name, 
	   payment;
end $$;

counter变量是一个整数,初始化为 1。

first_namelast_namevarchar(50)类型,并初始化为'John''Doe'字符串常量。

payment的类型为 numeric,其值初始化为20.5

变量初始化时序

PostgreSQL 计算变量的默认值,并在进入代码块时将其分配给变量。例如:

do $$ 
declare
   created_at time := now();
begin 
   raise notice '%', created_at;
   perform pg_sleep(10);
   raise notice '%', created_at;
end $$;

这是输出:

NOTICE:  14:23:33.064008
NOTICE:  14:23:33.064008

在这个例子中:

  • 首先,声明一个变量,其默认值初始化为当前时间。
  • 其次,打印出变量的值,并使用pg_sleep()函数在 10 秒内通过执行。
  • 第三,再次打印出created_at变量的值。

从输出中可以清楚地看出,created_at的值仅在进入代码块时初始化一次。

复制数据类型

%type提供了一个表列或另一个变量的数据类型。通常,您使用%type来声明变量,保存来自数据库或其他变量的值。

下面说明如何声明具有一个表列的数据类型的变量:

variable_name table_name.column_name%type;

下面展示了如何使用另一个变量的数据类型来声明一个变量:

variable_name variable%type;

请参阅示例数据库中如下的 film 表:

img

此示例使用类型复制技术来声明保存来自film表的值的变量:

do $$ 
declare
   film_title film.title%type;
   featured_title film_title%type;
begin 
   -- get title of the film id 100
   select title
   from film
   into film_title
   where film_id = 100;
   
   -- show the film title
   raise notice 'Film title id 100: %s', film_title;
end; $$

此示例声明了两个变量:

  • film_title变量与示例数据库film表中的title列具有相同的数据类型。
  • featured_title变量的数据类型与film_title变量的数据类型相同。

通过使用类型复制功能,您可以获得以下优势:

  • 首先,您不需要知道所引用的列或引用的类型。
  • 其次,如果引用的列名(或变量)的数据类型发生变化,则无需更改函数的定义。

块和子块中的变量

当您在子块中声明一个与外部块中的另一个变量同名的变量时,外部块中的变量将在子块中被隐藏。

如果您想要访问外部块中的变量,可以使用块标签来限定其名称,如下例所示:

do $$ 
<<outer_block>>
declare
  counter integer := 0;
begin
   counter := counter + 1;
   raise notice 'The current value of the counter is %', counter;

   declare
       counter integer := 0;
   begin
       counter := counter + 10;
       raise notice 'Counter in the subblock is %', counter;
       raise notice 'Counter in the outer block is %', outer_block.counter;
   end;

   raise notice 'Counter in the outer block is %', counter;
   
end outer_block $$;
NOTICE:  The current value of the counter is 1
NOTICE:  Counter in the subblock is 10
NOTICE:  Counter in the outer block is 1
NOTICE:  Counter in the outer block is 1

在这个例子中:

  • 首先,在outer_block块中声明一个名为counter的变量。
  • 接下来,在子块中声明一个同名的变量。
  • 然后,在进入子块之前,counter 的值为 1。在子块中,我们将counter的值增加到 10 并将其打印出来。请注意,更改仅影响子块中的counter变量。
  • 之后,使用块标签引用外部块中的counter变量,以限定其名称outer_block.counter
  • 最后,打印出外部块中counter变量的值,其值保持不变。

在本教程中,您学习了声明 PL/pgSQL 变量的各种方法。