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

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

猜你喜欢

转载自blog.csdn.net/superSmart_Dong/article/details/107053192
今日推荐