定义变量
介绍PL/SQL中变量的声明,以及该变量在代码中的作用域。
变量声明
变量声明语法请参见图1。
对以上语法格式的解释如下:
- 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不支持引用复合类型或RECORD类型变量的类型、RECORD类型的某列类型、跨PACKAGE复合类型变量的某列类型、跨PACKAGE cursor变量的某列类型等。
- %ROWTYPE不支持引用复合类型或RECORD类型变量的类型、跨PACKAGE cursor的类型。
- 若使用%TYPE操作从record变量.column中取得类型,且该record变量.column的类型由%TYPE操作定义,则不会保留原始类型的约束(带约束的数据类型如NUMBER(3)、VARCHAR2(10)等)。
变量作用域
变量的作用域表示变量在代码块中的可访问性和可用性。只有在它的作用域内,变量才有效。
- 变量必须在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;
/