#引用变量
本文档描述%TYPE和%ROWTYPE两种引用变量类型。
# %TYPE
在声明变量时,通过指定%TYPE可以使变量的数据类型与其他某个变量或列字段的数据类型相同,当变量用于存储其他某个变量或列字段的值时,使用%TYPE可以在声明时不必知道对方的数据类型直接进行引用,且如果对方的数据类型发生变更时,无需改动声明。
除用于声明变量外,%TYPE还可以作为PROCEDURE的参数,FUNCTION的参数或者返回值。
当%TYPE引用的对象为列字段时,将只引用该列字段的数据类型,其他如NOT NULL等约束项不会被继承,且在列字段上定义的DEFAULT值也不会被继承。
当%TYPE引用的对象为其他某个变量时,该变量上的NOT NULL属性将被继承,但初始值不会被继承,基于此规则,如果引用的变量指定了NOT NULL,则必须为%TYPE变量定义初始值。
变量类型
可以被%TYPE引用的变量包括:
- 普通变量
- 游标
- RECORD
- RECORD的成员,为record_name.member_name形式
- label与上述变量的结合,为label.变量名形式
声明%TYPE类型变量的格式为:
变量名 (被引用的变量名|表名.列名)%TYPE[:=初始值];
匹配规则
对于上述中出现的label.变量名、record_name.member_name和表名.列名三种字面表现相同的形式,系统定义如下匹配规则以确定%TYPE的引用对象:
- 按record_name.member_name>label.变量名>表名.列名的优先级进行匹配。
- 当"."前面的item匹配上时,上条优先级规则不再有效,而是只对本种形式进行匹配,此时如"."后面的item未匹配成功,则系统报错。
示例
DROP TABLE IF EXISTS table_type;
CREATE TABLE table_type(a VARCHAR(10));
INSERT INTO table_type VALUES('helloworld');
COMMIT;
--tb_type与tb_recode匹配,但a与aa不匹配,此时报错而不执行label.变量名匹配
<<tb_type>>
DECLARE
TYPE tb_record IS RECORD (aa CHAR(12));
a VARCHAR(11);
tb_type tb_record;
b tb_type.a%TYPE;
BEGIN
b := 'helloworld';
DBMS_OUTPUT.PUT_LINE(b);
END;
/
YAS-04253 PL/SQL compiling errors:
[7:3] YAS-05246 invalid tb_type.a%type
[9:1] YAS-04243 invalid identifier "B"
[10:22] YAS-04243 invalid identifier "B"
# %ROWTYPE
通过%ROWTYPE声明的变量为一个RECORD,且该RECORD的成员来自于%ROWTYPE所引用对象的成员,包括成员的名称和类型。
可以被%ROWTYPE引用的对象有:
- 表/视图,可通过别名引用
- 游标
其中,引用游标表示引用的是该游标的返回值RECORD,包括显式定义的返回值,以及未显式定义返回值时,系统隐式生成的返回值(即游标绑定的SQL语句的列项)。
RECORD的成员为被引用对象所拥有的全部列或成员,无法进行部分引用。
示例
DECLARE
a area%ROWTYPE;
TYPE cursor IS REF CURSOR RETURN area%ROWTYPE;
cur cursor;
ano_cur cur%ROWTYPE;
BEGIN
a.area_no := '88';
a.area_name := 'ref column';
DBMS_OUTPUT.PUT_LINE('first record:' || a.area_no || ',' || a.area_name);
OPEN cur FOR SELECT * FROM area;
FETCH cur INTO ano_cur;
DBMS_OUTPUT.PUT_LINE('third record:' || ano_cur.area_no || ',' || ano_cur.area_name);
CLOSE cur;
END;
/
--output
first record:88,ref column
third record:01,华东