22.6 使用%TYPE和%ROWTYPE类型的变量
在定义变量时,除了可以使用Oracle规定的数据类型外,还可以使用%TYPE和%ROWTYPE来定义变量。
%TYPE类型的变量是专门为存储从数据列中检索到的值而创建的。对于使用%TYPE创建的变量,其数据类型由系统根据检索的数据列的数据类型决定。
而对于%ROWTYPE类型的变量而言,它可以一次存储从数据库检索的一行数据。
22.6.1 %TYPE变量
如果用户事先不知道检索的数据列的数据类型时,就可以考虑使用%TYPE来定义变量。
当使用%TYPE定义变量时,其数据类型为指定的列的数据类型。请看下面的示例:
SQL> declare
2 empno emp.empno%TYPE; //声明的时候一定要加上表的中列
3 ename emp.ename%TYPE;
4 job emp.job%TYPE;
5 begin
6 select empno,ename,job into empno,ename,job from emp where empno='7369';
7 dbms_output.put_line(empno||'/'||ename||'/'||job);
8 end;
9 /
7369/SMITH/CLERK
在上面的程序中,对于emp.empno%TYPE来说,首先系统会从emp表中去查找empno列,再然后%TYPE返回其数据类型。
%TYPE的好处:
1、可移植性高(当我们对表的数据类型发生改变时,用户不必考虑定义变量类型)。
2、 用户不必查看数据类型就可以定义变量能够存储检索的数据。
22.6.2 %ROWTYPE变量
与%TYPE类型相似,也可以在不确定查询列的数据类型的情况下,使用%ROWTYPE类型的变量存储查询的数值,只不过%ROWTYE一次可以存储一行数据。例如,下面的示例使用%ROWTYPE类型的变量存储查询的数据。
SQL> declare
2 row_data emp%ROWTYPE;
3 begin
4 select * into row_data from emp where empno='7369';
5 dbms_output.put_line(row_data.empno||'/'||row_data.ename||'/'||row_data.job);
6 end;
7 /
在上面的程序中,定义了一个%ROWTYPE类型的变量,该变过量的结构与“emp”表的结构完全相同。因此,可以将检索的一整行数据保存到该变量中,并且根据表中列的名称引用对应的数值。
注意:如果定义了%rowtype类型的变量,由于该变量的结构与定义表的结构完全相同,所以查询时必须使用 * 或者列举表的全部字段信息。
22.7 复合变量
复合变量可以将不同的数据类型的多个值存储在一个单元中。由于复合数据类型可以有用户根据需要定义其结构,所以复合数据类型也称为自定义数据类型。
PL/SQL提供了两种类型的复合数据类型:
22.7.1 记录类型
记录类型与数据库中的行结构非常相似,使用记录类型定义的变量可以存储由多个列组成的一行数据。
当使用记录类型的变量时,首先需要定义记录的结构,然后设定记录类型的变量,这与定义变量和%TYPE、%ROWTYPE类型的变量不同。
使用TYPE语句定义记录类型的语法形式如下:
TYPE record_name is record(
Field_name data_type [not null] [:=default value]
…
);
其中,record_name为自定义的记录类型的名称,field_name为记录类型中的字段名,data_type为该字段的数据类型。记录与%Rowtype不同之处是:
1、%rowtype查询的是全部数据
2、记录类型必须使用type语法格式声明
//案例
SQL> declare
2 type empinfo is record( //声明一个记录类型
3 empno number(4),
4 ename varchar2(10),
5 job varchar2(9)
6 );
7
8 emp_data empinfo; //声明一个记录类型的变量
9 begin
10 select empno,ename,job into emp_data from emp where empno=7369; //查询的结果赋值给定义的变量
11 dbms_output.put_line(emp_data.empno||'/'||emp_data.ename||'/'||emp_data.job);
12 end;
13 /
22.7.2 记录表类型
记录表允许用户在程序代码中使用“表”,以便存储多个行的数据。它只在程序运行期间有效,类似于程序代码中的集合(数组)。
为什么使用记录表类型呢?因为我们查询的数据往往需要返回多行记录,所以需要记录表类型。
定义记录表类型的语法形式:
TYPE table_name is table of data_type[not null]
Index by binary_integer;
由于记录表类型不会存储在数据库中,所以data_type可以是任何合法的PL/SQL数据类型。关键字INDEX_BY BINARY_INTEGER指示系统创建一个主键索引,以引用记录表变量中的特定行。在下面的示例中,创建了两种不同的记录表数据类型:
declare
type table_emp is table of emp%rowtype //创建一个表,此表的类型与emp表的类型一致
index by binary_integer;
type table_text is table of varchar2(20) //创建一个表 此表具有一个varchar2列的简单表
index by binary_integer;
empt table_emp; //声明记录表类型的变量
tabtext table_text;
begin
null
end;
案例:
SQL> declare
2 type table_emp is table of emp%rowtype
3 index by binary_integer;
4 empt table_emp;
5 begin
6 empt(1).ename:='wangyi';
7 dbms_output.put_line(empt(1).ename);
8 end;
9 /
//返回总记录
SQL> declare
2 type table_emp is table of emp%rowtype
3 index by binary_integer;
4 empt table_emp;
5 begin
6 dbms_output.put_line(empt.count);
7 end;
8 /
0 //没有记录
删除记录表变量中的记录
表名.Delete(记录数);
检索记录变量
First:获取第一个的索引
Next:下一个的索引 但是必须有参数
Last:最后一个的索引
SQL> declare
2 type table_emp is table of emp%rowtype
3 index by binary_integer;
4 empt table_emp;
5 i number(2):=1;
6 begin
7 while i<10
8 loop
9 empt(i).ename:='wangyi';
10 i:=i+1;
11 end loop;
12
13 dbms_output.put_line(empt.count);
14
15 empt.delete(2);
16
17 dbms_output.put_line(empt.count);
18
19 dbms_output.put_line(empt.first);
20 dbms_output.put_line(empt.next(2));
21 dbms_output.put_line(empt.last);
22 end;
23 /
9
8
1
3
9