数组分为固定长度数组和可变长度数组,都是集合,且数组的起始下标是从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; /