更新时间:2024-08-20 GMT+08:00

定义变量

介绍PL/SQL中变量的声明,以及该变量在代码中的作用域。

变量声明

变量声明语法请参见图1

图1 declare_variable::=

对以上语法格式的解释如下:

  • variable_name:变量名。
  • type:变量类型。
  • value:该变量的初始值(如果不给定初始值,则初始为NULL)。value也可以是表达式。

1
2
3
4
5
6
7
gaussdb=# DECLARE
    emp_id  INTEGER := 7788;  --定义变量并赋值
BEGIN
    emp_id := 5*7784;  --变量赋值
END;
/
ANONYMOUS BLOCK EXECUTE

变量类型除了支持基本类型,还可以是使用%TYPE和%ROWTYPE去声明一些与其他表字段或表结构本身相关的变量。

%TYPE属性

%TYPE主要用于声明某个与其他变量类型(例如:表中某列的类型)相同的变量。假如定义一个my_name变量,它的变量类型与employee的firstname类型相同,可以通过如下定义:

my_name employee.firstname%TYPE
--示例
DROP TABLE IF EXISTS employee;
NOTICE:  table "employee" does not exist, skipping
DROP TABLE
CREATE TABLE employee(firstname varchar,secondname varchar);
CREATE TABLE
DECLARE
    my_name employee.firstname%TYPE;
BEGIN
    my_name = 'abc';
    DBE_OUTPUT.PRINT_LINE(my_name);
END;
/
abc
ANONYMOUS BLOCK EXECUTE

这样定义可以带来两个好处:首先,不用预先知道employee表的firstname字段的数据类型。其次,即使之后firstname字段的数据类型有了变化,也不需要再次修改my_name的数据类型。

TYPE employee_record is record (id INTEGER, firstname VARCHAR2(20));
my_employee employee_record;
my_id my_employee.id%TYPE;
my_id_copy my_id%TYPE;
--示例
DECLARE
    TYPE employee_record is record (id INTEGER, firstname VARCHAR2(20));
    my_employee employee_record;
    my_id my_employee.id%TYPE;
    my_id_copy my_id%TYPE;
BEGIN
    my_employee.id := 1;
    my_employee.firstname := 'ab2';
    my_id = 2;
    my_id_copy = 3;
    DBE_OUTPUT.PRINT_LINE(my_employee.id);
    DBE_OUTPUT.PRINT_LINE(my_employee.firstname);
    DBE_OUTPUT.PRINT_LINE(my_id);
    DBE_OUTPUT.PRINT_LINE(my_id_copy);
END;
/
1
ab2
2
3
ANONYMOUS BLOCK EXECUTE

%ROWTYPE属性

%ROWTYPE属性主要用于对一组数据的类型声明,用于存储表中的一行数据或从游标匹配的结果。假如,需要一组数据,该组数据的字段名称与字段类型都与employee表相同。可以通过如下定义:

my_employee employee%ROWTYPE
--示例
DROP TABLE IF EXISTS employee;
DROP TABLE
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;
/
ab1
ab2
ANONYMOUS BLOCK EXECUTE

同样可以使用在cursor上面,该组数据的字段名称与字段类型都与employee表相同(对于PACKAGE中的cursor,可以省略%ROWTYPE)。%TYPE也可以引用cursor中某一列的类型,可以通过如下定义:

cursor cur is select * from employee;
my_employee cur%ROWTYPE
my_name cur.firstname%TYPE
my_employee2 cur -- 对于PACKAGE中定义的cursor,可以省略%ROWTYPE字段
--示例
set behavior_compat_options = 'allow_procedure_compile_check';
SET
DROP TABLE IF EXISTS employee;
DROP TABLE
CREATE TABLE employee(firstname varchar,secondname varchar);
CREATE TABLE
CREATE OR REPLACE procedure proc1()
IS
    cursor cur is select * from employee;
    my_employee cur%ROWTYPE;
    my_name cur.firstname%TYPE;
BEGIN
    my_employee.firstname := 'ab1';
    my_employee.secondname := 'ab2';
    my_name := 'ab3';
    DBE_OUTPUT.PRINT_LINE(my_employee.firstname);
    DBE_OUTPUT.PRINT_LINE(my_employee.secondname);
    DBE_OUTPUT.PRINT_LINE(my_name);
END;
/
CREATE PROCEDURE
  • %TYPE仅支持引用跨PACKAGE的record类型的变量、不支持引用cursor变量的某列类型等。
  • 开启GUC参数behavior_compat_options,且该参数的值包含allow_procedure_compile_check后,%TYPE可支持引用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变量作为参数类型或者出入参类型。

变量作用域

变量的作用域表示变量在代码块中的可访问性和可用性。只有在它的作用域内,变量才有效。

  • 变量必须在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;
/
inner emp_id =7799
outer_var =6688
outer emp_id =7788
ANONYMOUS BLOCK EXECUTE