1.记录的类型
1.1基于表和游标的记录
记录结构类似于数据库表的一行数据。使用%ROWTYPE属性,可以创建基于表和游标的记录。
示例:
declare
v_table_student student%Rowtype;--基于表的记录;
cursor cur_student is select * from student; --静态游标
v_cur_student cur_student%Rowtype;--基于游标的记录
begin
dbms_output.put_line('--------下面是基于表的记录----------------');
--取行数据存入 基于表的记录
select * into v_table_student from student where student.STUDENT_ID=167;
dbms_output.put_line(v_table_student.STUDENT_ID||';'||v_table_student.FIRST_NAME);
dbms_output.put_line('--------下面是基于游标的记录----------------');
open cur_student;
loop --遍历游标
fetch cur_student into v_cur_student;--取游标行的数据存入 基于游标的记录中
exit when cur_student%notfound;
dbms_output.put_line(v_cur_student.STUDENT_ID||';'||v_cur_student.FIRST_NAME);
end loop;
end;
1.2基于用户定义的记录
自定义记录的语法:
TYPE type_name is record (
field_name1 datatype1 [not null][:Default Expression],
field_name2 datatype1 [not null][:Default Expression]
);
record_name TYPE_NAME;
示例:
type rec_student is record (
r_student_id student.STUDENT_ID%type,
r_student_name student.LAST_NAME%type,
r_nl char(1) not null:='c' --可以指定not null约束,此时初始化时必须赋值
);
v_rec_student rec_student;
练习:
declare
--用户自定义记录
type rec_student is record (
r_student_id student.STUDENT_ID%type,
r_student_name student.LAST_NAME%type,
r_nl char(1) not null:='c'
);
v_rec_student rec_student;
begin
dbms_output.put_line('--------下面是基于用户自定义记录的记录----------------');
select student.STUDENT_ID,student.LAST_NAME into v_rec_student.r_student_id,v_rec_student.r_student_name from student where student.STUDENT_ID=167;
dbms_output.put_line(v_rec_student.r_student_id||';'||v_rec_student.r_student_name||';'||v_rec_student.r_nl);
end;
1.3记录兼容性
注意:
两个自定义记录,即使有相同的结构,但每个记录类型不同,不可以互相赋值。对于基于表的记录或基于游标的记录赋予自定义类型不受限制。
示例:
DECLARE
type type_record1 is record( first_name varchar2(20),last_name varchar2(20));
type type_record2 is record(first_name varchar2(20),last_name varchar2(20));
v_record1 type_record1;
v_record2 type_record2;
--基于游标记录
cursor cur_test is select * from t_test;
v_cur_test cur_test%Rowtype;
--基于自定义记录的记录
type rec_test is record(id number,name varchar2(20));
v_rec_test rec_test;
--基于表的记录
v_test t_test%rowtype;
begin
v_record1.first_name:='a';
v_record1.last_name:='b';
--v_record2:=v_record1;--报错,原因:两个自定义记录,即使有相同的结构,但每个记录类型不同,不可以互相赋值。
open cur_test;
loop
fetch cur_test into v_cur_test;
exit when cur_test%notfound;
end loop;
v_test:=v_cur_test;
v_rec_test:=v_cur_test;
end;
2.嵌套记录
包含嵌套记录或者集合的记录被称为封装记录。
示例:
declare
type type_name is record (fName t_test.FNAME%type,lname t_test.LNAME%type);
type r_test is record(id number,name type_name,age number);
v_r_test r_test;
begin
select t_test.ID,t_test.FNAME,t_test.LNAME,t_test.AGE into
v_r_test.id,v_r_test.name.fName,v_r_test.name.lname,v_r_test.age --注意赋值时的差别
from t_test
where t_test.ID=2;
dbms_output.put_line('id:'||v_r_test.id);
dbms_output.put_line('fName:'||v_r_test.name.fName);--注意取出时的差别
dbms_output.put_line('Lname:'||v_r_test.name.Lname);
dbms_output.put_line('age:'||v_r_test.age);
end;
3.记录的集合
元素类型是基于游标的记录或者基于表的记录或者基于用户自定义记录的集合(索引表、嵌套表、变长数组)。
示例:
declare
cursor cur_name is select last_name,first_name from student where rownum<=4;
type type_plsql_name is table of cur_name%rowtype index by binary_integer;
type type_qt_name is table of cur_name%rowtype;
v_plsql_tab type_plsql_name;
v_qt_table type_qt_name:=type_qt_name();
v_counter integer:=0;
v_i integer:=0;
begin
for r_name in cur_name loop
v_counter:=v_counter+1;
v_plsql_tab(v_counter).last_name:=r_name.LAST_NAME;
v_plsql_tab(v_counter).first_name:=r_name.FIRST_NAME;
dbms_output.put_line(v_plsql_tab(v_counter).last_name||';'||v_plsql_tab(v_counter).first_name);
end loop;
dbms_output.put_line('------分隔线 以下是嵌套表-------------------');
for r_name in cur_name loop
v_i:=v_i+1;
v_qt_table.extend;
v_qt_table(v_i).last_name:=r_name.LAST_NAME;
v_qt_table(v_i).first_name:=r_name.FIRST_NAME;
dbms_output.put_line(v_qt_table(v_i).last_name||';'||v_qt_table(v_i).first_name);
end loop;
end;