Oracle 原理: 集合数组,集合属性,is table of 用法,bulk collect into,IS RECORD用法

    技术2022-07-10  94

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

     

    Processed: 0.031, SQL: 9