oracle中的集合分为:联合数组,嵌套表,可变数组三种类型。
1、联合数组
索引表(key-value形式),索引值可以是无序的, 可以数字或字符串为下标来查找集合中的元素,元素数量不限。
定义:
TYPE JOIN_LIST IS TABLE of dataType index by indexType;
JOIN_LIST:数组的名字
dataType:指定的数组的数据类型
indexType:指定的数组的索引的类型
简单实例:
1.1、以数字类型为索引的联合数组:
declare
TYPE JOIN_LIST IS TABLE of number index by BINARY_INTEGER;
v_number JOIN_LIST;
begin
for i in 1 .. 5 loop
v_number(i) := i * 10;
end loop;
begin
for i in 1..5 loop
dbms_output.put_line('v_number('||i||'):' || v_number(i));
end loop;
dbms_output.put_line('v_number(6):' || v_number(6));--当引用不存在的元素会报no data found 异常
EXCEPTION
when NO_DATA_FOUND then
dbms_output.put_line('no data found reading v_number(6)!');
end;
end;
v_number.delete;--删除整个数组
v_number.delete(n);--删除索引为n的数组,如果元素不存在直接跳过,不会报错
v_number.delete(n,m);--删除索引从n到m的元素
1.2、以字符串类型为索引的联合数组
declare
TYPE JOIN_LIST IS TABLE of number index by varchar2(20);
v_string JOIN_LIST;
i varchar2(30);
begin
v_string('a') := 10;
v_string('b') := 20;
v_string('c') := 30;
i := v_string.FIRST;
WHILE i is not null loop
dbms_output.put_line(i || ' number is:' || v_string(i));
i := v_string.NEXT(i);
end loop;
EXCEPTION
when NO_DATA_FOUND then
dbms_output.put_line('no data found reading v_number(5)!');
end;
2、嵌套表
2.1基本使用
适用于嵌套表的情况:
元素的数量不确定,索引值不连续,需要同时删除和更新部分元素,而不是全部元素,需要创建一个独立的表查找;
declare
type nesttable is table of varchar2(50);
v_table1 nesttable;
v_table2 nesttable := nesttable();
v_table3 nesttable := nesttable(null);
v_table4 nesttable := nesttable('tom', 'joan', 'sandy');
begin
if v_table1 is null then
dbms_output.put_line('v_table1 is null !');
else
dbms_output.put_line('v_table1 is not null !');
end if;
if v_table2 is null then
dbms_output.put_line('v_table2 is null !');
else
dbms_output.put_line('v_table2 is not null !');
end if;
if v_table3 is null then
dbms_output.put_line('v_table3 is null !');
else
dbms_output.put_line('v_table3 is not null !');
end if;
if v_table4 is null then
dbms_output.put_line('v_table4 is null !');
else
dbms_output.put_line('v_table4 is not null !');
end if;
for i in v_table4.first .. v_table4.last loop
dbms_output.put_line(v_table4(i));
end loop;
v_table1(1) := 100;
EXCEPTION
WHEN COLLECTION_IS_NULL THEN
dbms_output.put_line('the v_table1 is not initialized');
end;
没有初始化的嵌套表为空(初始化 v_table2 nesttable := nesttable(););
不带参数的构造器会创建一个没有元素的嵌套表,该嵌套表不为空;
带null参数的构造器会创建一个非空的嵌套表,改嵌套表的第一个元素为空,引用第二个以后(没有元素)报错;
如果应用没有初始化的嵌套表会报collection_is_null异常;
2.2 操作嵌套表
赋值: v_table1(1) := 100;
初始化赋值:
v_test nesttable:= nesttable(100,200);
dbms_output.put_line(v_test(1));--100
dbms_output.put_line(v_test(2));--200
dbms_output.put_line(v_test(3));--报错subscript_beyond_count
元素的添加:
extend:在嵌套表的末尾添加一个元素,元素值为null;
extend(n):在嵌套表末尾添加n个元素,元素值为null;
extend(n,i):在元素末尾添加n个元素,元素值为索引为i的元素的值;
declare
cursor all_menu is
select * from t_story_others where user_code = 'lwx458668';
type nesttable is table of t_story_others%rowtype;
v_table2 nesttable := nesttable();
numb number := 1;
begin
for i in all_menu loop
v_table2.extend;
v_table2(numb) := i;
numb := numb + 1;
end loop;
for j in v_table2.first .. v_table2.last loop
dbms_output.put_line(v_table2(j).content);
end loop;
dbms_output.put_line(v_table2(4).content);
EXCEPTION
WHEN SUBSCRIPT_BEYOND_COUNT THEN
dbms_output.put_line('the v_table1 is not initialized');
end;
2.3、嵌套表删除
delete方法的使用与联合数组的使用方法一致
trim :删除嵌套表的最后一个元素,并回收储存空间。
trim(n):从嵌套表末尾删除n个元素,并回收储存空间。
delete方法删除后还可以通过赋值重新引用改元素,trim删除后会回收存储空间,不可以再引用该元素。
declare
cursor all_menu is
select * from t_story_others where user_code = 'lwx458668';
type nesttable is table of t_story_others%rowtype;
v_table2 nesttable := nesttable();
numb number := 1;
begin
for i in all_menu loop
v_table2.extend;
v_table2(numb) := i;
numb := numb + 1;
end loop;
v_table2.delete(1);
for j in v_table2.first .. v_table2.last loop
if v_table2.exists(j) then
dbms_output.put_line(v_table2(j).content);
end if ;
end loop;
dbms_output.put_line(v_table2(4).content);
EXCEPTION
WHEN SUBSCRIPT_BEYOND_COUNT THEN
dbms_output.put_line('the v_table1 is not initialized');
end;
3 、可变数组
长度是在定义的时候确定的,使用时不可变;
可变数组为密集集合,不能删除可变数组的元素而形成间隙;
可作为独立的数据库对象存储在数据库服务器中,是全局的数据类型;
可变数组必须使用构造器初始化后才能使用,没有初始化的可变数组的自动赋值为null;
3.1初始化和使用:
TYPE VARCHAR_ARRAY IS VARRAY ( 9999 ) OF varchar2 ( 2 );--创建一个长度为9999的varchar2类型的数组
create or replace procedure array_test(array_out out varchar_array) as
begin
array_out :=varchar_array();
for i in 1..100 loop
array_out.extend;
array_out(i)=i;
end loop;
end;
遍历:
declare
e_array VARCHAR_ARRAY;
begin
array_test(e_array);
for i in 1..e_array.count loop
dbms_output.put_line(i||':'||e_array(i));
end loop;
end;
3.2操作可变数组
e_array(2) :='a';
e_array.trim(2);--删除最后两个元素
e_array.extend(1,2);添加一个元素,值和索引为2的值一样
可能会出现的异常
COLLECTION_IS_NULL:引用未初始化的数组
SUBSCRIPT_BEYOND_COUNT:下面索引值超过数组中实际元素的个数
SUBSCRIPT_OUTSIDE_LIMIT:下面索引值超过可变数组的最大值