定义变量
介绍PL/SQL中变量的声明,以及该变量在代码中的作用域。
变量声明
变量声明语法如图1所示。
对以上语法格式的解释如下:
- variable_name,为变量名。
- type,为变量类型。
- value,是该变量的初始值(如果不给定初始值,则初始为NULL)。value也可以是表达式。
示例
gaussdb=# DECLARE
emp_id INTEGER := 7788; --定义变量并赋值
BEGIN
emp_id := 5*7784; --变量赋值
END;
/ 变量类型除了支持基本类型,还可使用%TYPE和%ROWTYPE去声明一些与其他表字段或表结构本身相关的变量。
%TYPE属性
%TYPE主要用于声明某个与其他变量类型(例如,表中某列的类型)相同的变量。假如定义一个my_name变量,它的变量类型与employee表的firstname列类型相同,可以通过如下定义:
my_name employee.firstname%TYPE
--示例
DROP TABLE IF EXISTS employee;
CREATE TABLE employee(firstname varchar,secondname varchar);
DECLARE
my_name employee.firstname%TYPE;
BEGIN
my_name = 'abc';
DBE_OUTPUT.PRINT_LINE(my_name);
END;
/ 这样定义可以带来两个优势,首先,无需预先知道employee表的firstname列的数据类型。其次,当firstname列的数据类型发生变化时,也无需修改my_name的类型定义。
%ROWTYPE属性
%ROWTYPE属性主要用于声明一组数据的类型,用于存储表中的一行数据,或从游标匹配的结果中获取。若需要一组数据,其字段名称与字段类型均与employee表相同。可以通过如下定义:
my_employee employee%ROWTYPE
DROP TABLE IF EXISTS employee;
CREATE TABLE employee(firstname varchar,secondname varchar);
DECLARE
my_employee employee%ROWTYPE;
BEGIN
my_employee.firstname := 'ab1';
my_employee.secondname := 'ab2';
DBE_OUTPUT.PRINT_LINE(my_employee.firstname);
DBE_OUTPUT.PRINT_LINE(my_employee.secondname);
END;
/
- 多个CN的环境下,存储过程中无法声明临时表的%ROWTYPE及%TYPE属性。因为临时表仅在当前session有效,在编译阶段其他CN无法看到当前CN的临时表。故多个CN的环境下,会提示该临时表不存在。
- %TYPE不支持引用非跨PACKAGE的record类型的变量、不支持引用cursor变量的某列类型等。
- %ROWTYPE不支持引用复合类型或RECORD类型变量的类型。
- 不支持非PACKAGE的record变量%TYPE作为变量类型或者出入参类型。
- 不支持view%ROWTYPE、SCHEMA.view%ROWTYPE作为出入参类型。
- 不支持PACKAGE.record变量%TYPE、SCHEMA.PACKAGE.record变量%TYPE作为出入参类型。
- 不支持表/视图.column.column%TYPE、SCHEMA.表/视图.column.column%TYPE嵌套1层及以上,作为变量类型和或者出入参类型。
- 不支持record变量.column.column%TYPE、PACKAGE.record变量.column.column%TYPE嵌套1层及以上的record的某列类型,作为变量类型和或者出入参类型。
- 不支持PACKAGE.cursor变量%ROWTYPE、SCHEMA.PACKAGE.cursor变量%ROWTYPE等更多级的cursor变量作为参数类型或者出入参类型。
- 在匿名块中,游标的%ROWTYPE(即cursor_name%ROWTYPE)不包含列信息,在作为集合元素的基类型使用时,可能会出现异常,例如BULK COLLECT INTO。
变量作用域
变量的作用域定义了变量在代码块中的可访问性及可用性。变量仅在其作用域范围内有效。
- 变量必须在DECLARE部分声明,即必须建立BEGIN-……END块结构。该结构强制要求变量必须先声明后使用,即变量在过程中具有不同的作用域与生存期。
- 同一变量在不同作用域内可重复定义,内层作用域的定义会覆盖外层作用域的定义。
- 外部块中定义的变量可在嵌套块中使用,但嵌套块的变量无法被外部块访问。
示例
gaussdb=# DECLARE
emp_id INTEGER :=7788; --定义变量并赋值
outer_var INTEGER :=6688; --定义变量并赋值
BEGIN
DECLARE
emp_id INTEGER :=7799; --定义变量并赋值
inner_var INTEGER :=6688; --定义变量并赋值
BEGIN
dbe_output.print_line('inner emp_id ='||emp_id); --显示值为7799
dbe_output.print_line('outer_var ='||outer_var); --引用外部块的变量
END;
dbe_output.print_line('outer emp_id ='||emp_id); --显示值为7788
END;
/
