数组分为固定长度数组和可变长度数组,都是集合,且数组的起始下标是从1开始的,这和其他高级程序语言不太一样。利用圆括号‘(下标)‘来获取值或者进行赋值。
一、固定长度的数组
固定长度的数组类型的声明 为 TYPE 类名 IS VARRAY(元素个数) OF 元素类型;
declare
type arry3 is varray(3) of varchar2(4); ---固定数组类型声明
sexsList arry3 :=arry3('男','女','人妖'); --固定数组变量定义
usr_input number;
begin
usr_input := &sexnum; --读取用户输入
sexsList(3) :='未知';
if usr_input <=sexsList.count and usr_input >0 then
dbms_output.put_line('你好'||sexsList(usr_input)); --用变量名(下标) 的形式赋值 := 或者读取
end if;
end ;
/
执行后输入:3 输出得
二、数组集合 count ,first ,last ,next() ,exists()的区别
declare
type varr_num is table of number INDEX BY PLS_INTEGER;
vnum varr_num;
vn number ;
begin
vnum(2) := 2000;
vnum(3) := 3000;
vnum(10) := 10000;
vnum(100) :=20000;
dbms_output.put_line('count:' ||vnum.count);
dbms_output.put_line('first:' ||vnum.first);
dbms_output.put_line('last:' ||vnum.last);
for i in 1..vnum.count loop
if not vnum.exists(i) then
dbms_output.put_line('不能找到vnum.count('||i||'):');
else
dbms_output.put_line('vnum.count('||i||'):' ||vnum(i));
end if ;
end loop;
vn :=vnum.first;
while vn is not null loop
dbms_output.put_line('vnum('||vn||'):' ||vnum(vn)||'vnum.next('||vn||'):' ||vnum.next(vn));
vn :=vnum.next(vn);
end loop;
dbms_output.put_line('vnum.next('||9||'):' ||vnum.next(9));
end;
/
输出结果
由此可以看出在集合属性中,
first : 第一个非空值的下标
last : 最后一个非空值的下标
count: 集合非零元素个数
next(i) :从i开始的下一个非空元素的下标
exists(i) : 下标i 是否有值 因为取元素为空时会报错,所以 vnum(i) is not null 无意义。
-------------------------------------------------------
新建表DEPARTMENT_TBL如下:
存储数据大致如下
----------------------------------------------------------------------
三、可变长度数组 IS TABLE OF 和 BULK COLLECT INTO :
declare
type varr_vchar is table of varchar2(20); --varchar2(20)的可变长度数组
deplist varr_vchar ;
begin
select department bulk collect into deplist from department_tbl;
dbms_output.put('该公司拥有的部门有:');
for i in 1 .. deplist.count loop
dbms_output.put_line(deplist(i));
end loop;
end;
/
TYPE 类名 IS TABLE OF 元素类型 [INDEX BY BINARY_INTEGER]; 指明了把结果集当做表; INDEX BY BINARY_INTEGER指明了当为number 类型时,下标自增长。如果没有指定下标自增长那么就要手动extend(i),来扩容数组大小。
declare
type numbers is table of varchar2(10);
m numbers := numbers();
begin
m.extend(10);
m(3) := '50';
m.extend;m.extend;m.extend;
m(6) := '60';
for i in 1 .. m.count loop
dbms_output.put_line(m(i));
end loop;
dbms_output.put_line('count:' ||m.count);
dbms_output.put_line('first:' ||m.first);
dbms_output.put_line('last:' ||m.last);
end;
/
输出结果:
SELECT 表字段集 BULK COLLECT INTO 类名 from 表名 ; 将数据集直接赋值给类变量,其效率比游标块,但是比游标更消耗内存。
declare
type varr_vchar is table of department_tbl%rowtype;
deplist varr_vchar ;
begin
select department,ALL_SALARY,LEADERS bulk collect into deplist from department_tbl;
dbms_output.put('该公司拥有的部门有:');
for i in 1 .. deplist.count loop
dbms_output.put_line(deplist(i).department ||'的总薪资为'||deplist(i).ALL_SALARY ||'元');
end loop;
end;
/
输出结果:
四、自定义结果集(对象数组):
结果集是可以自定义的,相当于面向对象程序里的 长度可变的对象数组。
TYPE 类名 IS RECORD (成员变量1 类型 , 成员变量2 类型 .......) ;
declare
type rec_dep is record (
department varchar2(10),
proportion number
);
type varr_vchar is table of rec_dep;
deplist varr_vchar ;
sumsalary number ; ----公司总薪资
begin
select sum(ALL_SALARY) into sumsalary from department_tbl;
---强行转换
select department,cast(ALL_SALARY/sumsalary as number(10,9))bulk collect into deplist from department_tbl;
for i in 1 .. deplist.count loop
dbms_output.put_line(deplist(i).department ||'的部门总薪资占公司比为'||deplist(i).proportion ||'%');
end loop;
end;
/