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_found
end;
###########################################################################################
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表中。
原文:http://fengsonglin.blog.51cto.com/9860507/1615240