5. Index-by表
5.1 index-by表的定义和操作 定义:由与数组类似的同质元素的集合组成的一种复合数据类型 特点:集合中的元素是稀疏分布的,没有限定的边界,只是由整数作为索引将其连接在一起,索引可以是正、负整数或者0(1)定义和赋值 A 定义数字类型的index-by表的类型declare type num_table is table of number index by binary_integer; --binary_integer:整数 v_example_tab num_table; v_num number:=13;begin v_example_tab(1):=1001; v_example_tab(2):=1002; v_example_tab(10):=1003; v_example_tab(-10):=1004; v_example_tab(0):=1005; v_example_tab(v_num):=1006; dbms_output.put_line(to_char(v_example_tab(0)));end; B 定义字符串类型的index-by表的类型declare type char_table is table of varchar2(20) index by binary_integer; --binary_integer:整数 v_example_tab char_table; v_num number:=13;begin v_example_tab(1):='xxxx'; v_example_tab(2):='yyhy'; v_example_tab(10):='asdf'; v_example_tab(-10):='asdfasd'; v_example_tab(0):='asd'; v_example_tab(v_num):='aseas1'; dbms_output.put_line(to_char(v_example_tab(v_num)));end; C 定义日期类型的index-by表的类型declare type char_table is table of date index by binary_integer; --binary_integer:整数 v_example_tab char_table; v_change varchar2(30);begin v_example_tab(1):=sysdate; v_example_tab(2):=sysdate+1; v_change:=to_char(v_example_tab(2),'yyyy-mm-dd'); dbms_output.put_line(v_change);end; D 还可以存储复合的数据类型declare type hrc_org_rec is record(hrc_code number,hrc_descr varchar2(20)); type num_table is table of hrc_org_rec index by binary_integer; v_example_tab num_table;begin v_example_tab(1).hrc_code:=1002; v_example_tab(1).hrc_descr:='adsfasdg'; --赋值方法 v_example_tab(2).hrc_code:=1003; v_example_tab(2).hrc_descr:='qweqr'; dbms_output.put_line(to_char(v_example_tab(1).hrc_code)); dbms_output.put_line(v_example_tab(1).hrc_descr);end; (2) 访问未定义的行declare type num_table is table of number index by binary_integer; --binary_integer:整数 v_example_tab num_table; v_num number:=13;begin v_example_tab(1):=1001; v_example_tab(2):=1002; v_example_tab(10):=1003; v_example_tab(-10):=1004; v_example_tab(0):=1005; v_example_tab(v_num):=1006; dbms_output.put_line(to_char(v_example_tab(0))); dbms_output.put_line(to_char(v_example_tab(1))); --报错前的语句不受影响 dbms_output.put_line(to_char(v_example_tab(5))); --访问未定义的行会出错,程序终止,报no_data_found的错 dbms_output.put_line(to_char(v_example_tab(-10)));end; (3)通过赋值元素来创建index-by表的行declare type num_table is table of varchar2(20) index by binary_integer; v_example_tab num_table; v_num number:=13;begin for idx in 1..10 loop --for loop循环的循环结果可以是一个数字集合 v_example_tab(idx):=to_char(2*idx+1); end loop; for idx in 1..10 loop dbms_output.put_line(v_example_tab(idx)); end loop;end;(4) 删除index-by表的内容,整个index-by的内容删除掉declare type num_table is table of number index by binary_integer; v_example_tab num_table; v_example_tab1 num_table; --未进行初始化,空的index-by表 v_num number:=13;begin v_example_tab(1):=1001; v_example_tab(2):=1002; v_example_tab(10):=1003; v_example_tab(-10):=1004; v_example_tab(0):=1005; v_example_tab(v_num):=1006; v_example_tab:=v_example_tab1; --用未初始化的index-by表赋值方式删除 dbms_output.put_line(to_char(v_example_tab(0))); --报错:no_data_foundend; ###########################################################################################5.2 index-by表的相关方法
(1) exists方法 --判断元素是否存在declare type num_table is table of number index by binary_integer; v_example_tab num_table; v_num number:=13;begin v_example_tab(1):=1001; v_example_tab(2):=1002; v_example_tab(10):=1003; v_example_tab(-10):=1004; v_example_tab(0):=1005; v_example_tab(v_num):=1006; if v_example_tab.exists(-5) then dbms_output.put_line('YES'); else dbms_output.put_line('NO'); end if;end; (2) count方法 -- 取index-by表元素的个数,就是计算已经定义的index-by的行(索引、下标)的个数declare type num_table is table of number index by binary_integer; v_example_tab num_table; v_num number:=13; v number;begin v_example_tab(1):=1001; v_example_tab(2):=1002; v_example_tab(10):=1003; v_example_tab(-10):=1004; v_example_tab(0):=1005; v_example_tab(v_num):=1006; v:=v_example_tab.count; dbms_output.put_line(to_char(v));end; (3) delete方法 -- 删除元素declare type num_table is table of varchar2(20) index by binary_integer; v_example_tab num_table; v_num number;begin for idx in 1..10 loop v_example_tab(idx):=to_char(2*idx+1); end loop; v_num:=v_example_tab.count; dbms_output.put_line(to_char(v_num)); v_example_tab.delete(1); --删除index-by表中的对应的索引的值 v_example_tab.delete(5); v_example_tab.delete(7); v_num:=v_example_tab.count; dbms_output.put_line(to_char(v_num));end;结合exists方法使用输出index-by表中的元素declare type num_table is table of varchar2(20) index by binary_integer; v_example_tab num_table; v_num number;begin for idx in 1..10 loop v_example_tab(idx):=to_char(2*idx+1); end loop; v_num:=v_example_tab.count; dbms_output.put_line(to_char(v_num)); v_example_tab.delete(1); v_example_tab.delete(5); v_example_tab.delete(7); v_num:=v_example_tab.count; dbms_output.put_line(to_char(v_num)); for idx in 1..10 loop if v_example_tab.exists(idx) then dbms_output.put_line(to_char(v_example_tab(idx))); else dbms_output.put_line('NULL'); end if; end loop;end;(4) first last next prior方法 --取的都是索引值first方法:取index-by的第一个有值的元素(包含null值)的索引号。last方法: 取index-by的最后一个有值的元素(包含null值)的索引号。next方法:取index-by指定元素的下一个有值的元素(包含null值)的索引号prior方法:取index-by指定元素的上一个有值的元素(包含null值)的索引号案例:declare type num_table is table of varchar2(20) index by binary_integer; v_example_tab num_table; v_num number; idx number;begin for idx in 1..10 loop v_example_tab(idx):=to_char(2*idx+1); end loop; v_num:=v_example_tab.count; dbms_output.put_line(to_char(v_num)); v_example_tab.delete(1); v_example_tab.delete(5); v_example_tab.delete(7); v_num:=v_example_tab.count; dbms_output.put_line(to_char(v_num)); idx:=v_example_tab.first; loop if v_example_tab.exists(idx) then dbms_output.put_line(v_example_tab(idx)); end if; exit when idx=v_example_tab.last; --退出循环的条件满足idx等于最后一个不为空的元素的索引值 idx:=v_example_tab.next(idx); --每次循环用next方法将idx往后推,推到下一个不为null的元素的索引位置 end loop;end;(3) index-by表的赋值 引用记录的index-by表将一个记录类型作为存储的类型存在index-by表中 A 分散赋值declare type hrc_org_rec is record(hrc_org_id number,hrc_descr varchar2(20),org_short_name varchar2(30)); type num_table is table of hrc_org_rec index by binary_integer; v_example_table num_table; cursor csr_hrc_org is select hrc_org_seq.nextval hrc_org_id,h.hrc_descr,o.org_short_name from org_tab o,hrc_tab h where o.hrc_code=h.hrc_code; i integer:=1; begin for idx in csr_hrc_org loop v_example_table(i).hrc_org_id:=idx.hrc_org_id; --分散赋值 v_example_table(i).hrc_descr:=idx.hrc_descr; v_example_table(i).org_short_name:=idx.org_short_name; i:=i+1; end loop; for j in 1..v_example_table.count loop if v_example_table.exists(j) then dbms_output.put_line(to_char(v_example_table(j).hrc_org_id)); --分别输出 dbms_output.put_line(v_example_table(j).hrc_descr); dbms_output.put_line(v_example_table(j).org_short_name); end if; end loop;end; B 聚集赋值declare type hrc_org_rec is record(hrc_org_id number,hrc_descr varchar2(20),org_short_name varchar2(30)); type num_table is table of hrc_org_rec index by binary_integer; v_example_table num_table; cursor csr_hrc_org is select hrc_org_seq.nextval hrc_org_id,h.hrc_descr,o.org_short_name from org_tab o,hrc_tab h where o.hrc_code=h.hrc_code; i integer:=1; begin for idx in csr_hrc_org loop v_example_table(i):=idx; --聚集赋值的方法,将游标句柄赋给index-by,等于把游标字段中每个属性赋给了index-by基于记录的每个字段的属性 i:=i+1; end loop; for j in 1..v_example_table.count loop if v_example_table.exists(j) then dbms_output.put_line(to_char(v_example_table(j).hrc_org_id)); dbms_output.put_line(v_example_table(j).hrc_descr); dbms_output.put_line(v_example_table(j).org_short_name); end if; end loop;end; 练习: 创建一个emp_r表(empno number,sal number,hiredate date,dname varchar2(10)) 要求将员工的这四个属性字段存储在记录里,将这些员工的全部信息放置在一个index-by表中,循环的方式将这些取到的信息用记录插入的方式存储在emp_r表中。