1.概述
PL/SQL除支持标量数据类型(NUMBER、DATE、Varchar2),还支持复合数据类型(类似于C中的结构体)。
2.分类
索引表|嵌套表|变长数组|多层集合。
索引表:下标可以是负数,并且元素个数无限制,不可以作为表列的数据类型使用。
嵌套表: 下标从1开始,并且元素个数无限制,可以作为表列的数据类型使用。
变长数组:下标以1开始,并且元素个数有限制,可以作为表列的数据类型使用。
多层集合:元素类型为集合类型的集合。
3.索引表(联合数组)
3.1定义语法
TYPE type_name is table of element_type[not null] index by element_type; --TYPE定义索引表结构
table_name TYPE_NAME;--定义所使用的类型名称
引用语法:table_name(subscript); 3.2示例
declare
--索引表类型 定义格式 定义基于emp行记录的索引表类型
type type_plsql_emp is table of emp%Rowtype index by binary_integer;
--定义索引表类型的变量 v_emp;
v_emp type_plsql_emp;
begin
select * bulk collect into v_emp from emp ;
dbms_output.put_line(v_emp(1).empno);
end;
---也可以这样定义:
declare
--定义记录结构体:emp_rec
type emp_rec is record(
rempno emp.EMPNO%type,
rempname emp.ENAME%type
);
--索引表类型 定义格式
type type_plsql_emp is table of emp_rec index by binary_integer;
--定义索引表类型的变量 v_emp;
v_emp type_plsql_emp;
begin
select emp.EMPNO,emp.ENAME bulk collect into v_emp from emp ;
dbms_output.put_line(v_emp(1).rempno);
end;
示例二:
declare
cursor cur_name is select last_name from student where rownum<=10;
Type type_plsql_lastName is table of student.LAST_NAME%type index by BINARY_INTEGER;
v_lastName type_plsql_lastName;
v_count number :=0;
begin
for r_cur_name in cur_name loop
v_count:=v_count+1;
v_lastName(v_count):=r_cur_name.LAST_NAME; --引用索引表中的元素
dbms_output.put_line('last_name:'||v_lastName(v_count));
end loop;
end;
----
declare
cursor course_cur is select description from course;
type course_type is table of course.DESCRIPTION%type index by BINARY_INTEGER;
course_tab course_type;
v_counter integer:=0;
begin
for course_rec in course_cur loop
v_counter:=v_counter+1;
course_tab(v_counter):=course_rec.DESCRIPTION;
end loop;
dbms_output.put_line('course('||course_tab.first||'):'||course_tab(course_tab.first));
dbms_output.put_line('course('||course_tab.last||'):'||course_tab(course_tab.last));
dbms_output.put_line('------分隔线------');
for i in 1..course_tab.count loop
dbms_output.put_line('course('||i||'):'||course_tab(i));
end loop;
end;
4.嵌套表
4.1定义语法
TYPE type_name is table of element_type[not null] ; --TYPE定义嵌套表结构
table_name TYPE_NAME;--定义所使用的类型名称
注意:嵌套表必须先初始化,才能引用其中的元素。因为声明嵌套表时,嵌套表被自动设置为NULL,为引用其中的元素,必须使用名为构造器的系统定义函数进行初始化。
示例:
Type type_qt_lastName is table of student.LAST_NAME%type;
v_lastName_tab type_qt_lastName:=type_qt_lastName();
4.2集合方法
Extend:扩展集合规模。
COUNT:返回集合中元素的数量。
DELETE:删除集合中所有元素或指定范围的元素或特定元素。使用它时会保留被删除元素的占位符。
FIRST|last:返回集合中的第一个和最后一个元素的下标。
PRIOR|NEXT:返回指定集合下标的前序和后续下标。
Exist:元素在集合中,返回true。
TRIM:从集合的末尾删除一个或者指定数量的元素。使用它时不会保持被剪裁元素的占位符。
注意:EXTEND和TRIM不可用于索引表;delete 不可用于变长数组。
示例: declare
cursor cur_name is select last_name from student where rownum<=10;
Type type_qt_lastName is table of student.LAST_NAME%type;--比索引表少 index by element_type
v_lastName_tab type_qt_lastName:=type_qt_lastName(); --与索引表定义时相比必须初始化
v_count number :=0;
begin
for r_cur_name in cur_name loop
v_count:=v_count+1;
v_lastName_tab.extend;--扩展v_lastName_tab
v_lastName_tab(v_count):=r_cur_name.LAST_NAME;
end loop;
dbms_output.put_line('返回集中的元素的数量:'||v_lastName_tab.count);
dbms_output.put_line('返回集合中第一个元素的下标:'||v_lastName_tab.first);
dbms_output.put_line('返回集合中的最后一个元素的下标:'||v_lastName_tab.last);
dbms_output.put_line('返回集合中的第一个元素的下标的后续下标:'||v_lastName_tab.next(1));
dbms_output.put_line('返回集合中最后一个元素的下标的前序下标:'||v_lastName_tab.prior(10));
end;
4.3嵌套数组示例
declare
cursor course_cur is select description from course;
type course_type is table of course.DESCRIPTION%type;
course_tab course_type:=course_type();
v_counter integer:=0;
begin
for course_rec in course_cur loop
v_counter:=v_counter+1;
course_tab.extend;
course_tab(v_counter):=course_rec.DESCRIPTION;
end loop;
dbms_output.put_line('course('||course_tab.first||'):'||course_tab(course_tab.first));
dbms_output.put_line('course('||course_tab.last||'):'||course_tab(course_tab.last));
dbms_output.put_line('------分隔线------');
for i in 1..course_tab.count loop
dbms_output.put_line('course('||i||'):'||course_tab(i));
end loop;
dbms_output.put_line('------分隔线-- delete|trim用法----');
course_tab.delete(30);
course_tab(30):='New course';
dbms_output.put_line('course(30):'||course_tab(30));
course_tab.trim;
course_tab.extend; --缺少此名会报错 下标超出数量
course_tab(30):='New course';
end;
5.变长数组
5.1定义语法
TYPE type_name is {varray|varying array} {size_limit} of element_type[not null] ; --TYPE定义变长数组结构
table_name TYPE_NAME;--定义所使用的类型名称
它在使用前也必须先初始化,初始化方法与嵌套表初始化方法相同。 5.2示例
declare
cursor cur_city is select city from zipcode where rownum<=10;
type type_varray_city is varray(20) of zipcode.city%type;--变长数组类型
v_varray_city type_varray_city:=type_varray_city();--变长数组变量初始化
v_counter number:=0;
begin
for r_cur_city in cur_city loop
v_counter:=v_counter+1;
v_varray_city.extend;
v_varray_city(v_counter):=r_cur_city.CITY;
dbms_output.put_line('v_varray_city('||v_counter||'):'||v_varray_city(v_counter));
end loop;
dbms_output.put_line('--------分隔线--------');
for i in 1..v_varray_city.count loop
v_varray_city.extend(1,i);--给第个i元素添加1个副本
end loop;
for i in 1..20 loop
dbms_output.put_line('v_varray_city('||i||'):'||v_varray_city(i));
end loop;
end;
6.多层集合
6.1定义
它的元素类型为集合类型。如:变长数组的变长数组;索引表的索引表;索引表的嵌套数组。
6.2示例
declare
type varray_type1 is varray(4) of integer;
type varray_type2 is varray(3) of varray_type1;
varray1 varray_type1:=varray_type1(2,4,6,8);
varray2 varray_type2:=varray_type2(varray1);
begin
varray2.extend;
varray2(2):=varray_type1(1,2,3,4);
varray2.extend;
varray2(3):=varray_type1(4,5,6,7);
for i in 1..varray2.count loop
for j in 1..varray1.count loop
dbms_output.put_line('varray2('||i||')'||'('||j||')='||varray2(i)(j));
end loop;
end loop;
end;