集合:
PL/SQL 表存在两种类型:联合数组(正式说法是索引表)和嵌套表。它们具有相同的结构,并且都使用下标方式来访问数据行。两种类型之间的主要差别是:嵌套表可以存储在数据库列中,而联合数组不行。
1.联合数组
DECLARE
TYPE last_name_type IS TABLE OF student.last_name%TYPE
INDEX BY BINARY_INTEGER;
last_name_tab last_name_type;
如:
DECLARE
CURSOR name_cur IS SELECT last_name FROM student WHERE rownum <=10;
TYPE last_name_type IS TABLE OF student.last_name%TYPE
INDEX BY BINARY_INTEGER;
last_name_tab last_name_type;
v_counter INTEGER := 0;
BEGIN
FOR name_rec IN name_cur LOOP
v_counter := v_counter + 1;
last_name_tab(v_counter) := name_rec.last_name;
DBMS.OUTPUT.PUT_LINE( ' last_name ( ' || v_counter || ') : '|| last_name_tab(v_counter));
END LOOP;
END;
2.嵌套表 :首先必须初始化嵌套表,然后才能引用其中的元素。当声明嵌套表时,嵌套表被自动设置为NULL。
TYPE type_name IS TABLE OF element_type [NOT NULL];
table_name type_name;
在大多数情况下,无法预知特定嵌套表的值。所以如下语句会产生一个空的,但不是NULL 的嵌套表。
last_name_tab := last_name_type();
如:
DECLARE
CURSOR name_cur IS
SELECT last_name from student where rownum <=10;
TYPE last_name_type IS TABLE OF student.last_name%TYPE;
last_name_tab last_name_type := last_name_type();
v_counter INTEGER :=0;
BEGIN
FOR name_rec IN name_cur LOOP
v_counter := v_counter +1 ;
last_name_tab.EXTEND ;
last_name_tab(v_counter) := name_rec.last_name;
DBMS.OUTPUT.PUT_LINE(' last_name ('|| v_counter || ') : '|| last_name_tab(v_counter));
END LOOP;
END;
集合方法:
如果某特定元素存在于集合中,则EXISTS 会返回TRUE。该方法可以被用于避免SUBSCRIPT_OUTSIDE_LIMIT 异常。
COUNT 返回集合中元素的数量。
EXTEND 会扩展集合的规模。
DELETE 会删除集合中所有元素,指定范围的元素,或者特定元素。注意,PL/SQL会保存所删除元素的占位符。
FIRST 和 LAST 会返回集合中第一个和最后一个元素的下标。注意,如果嵌套表的第一个元素被删除,则FIRST 方法会返回大于1 的值。如果从嵌套表个删除一个中间元素,则LAST 方法的返回值会大于 COUNT 方法的返回值。
PRIOR 和 NEXT 会返回指定集合下标的前序和后续下标。
TRIM 会从集合的末尾删除一个,或者指定数量的元素。注意PL/SQL 不会保存被删除元素的占位符。
如:
DECLARE
TYPE index_by_type IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
index_by_table index_by_type;
type nested_type is table of NUMBER;
nested_table nested_type := nested_type(1,2,3,4,5,6,7,8,9,10);
BEGIN
--Populate index by table
for i in 1..10 loop
index_by_table(i) := i;
end loop;
if index_by_table.EXISTS(3) then
dbms_output.put_line('index_by_table (3) = ' || index_by_table(3));
end if;
--delete 10th element form a collection
nested_table.DELETE(10);
--delete elements 1 through 3 from a collection
nested_table.DELETE(1,3);
index_by_table.DELETE(10);
DBMS_OUTPUT.PUT_LINE('nested_table.COUNT = '|| nested_table.COUNT);
DBMS_OUTPUT.PUT_LINE('index_by_table.COUNT = '|| index_by_table.COUNT);
DBMS_OUTPUT.PUT_LINE('nested_table.FIRST = '|| nested_table.FIRST);
DBMS_OUTPUT.PUT_LINE('nested_table.LAST = '|| nested_table.LAST);
DBMS_OUTPUT.PUT_LINE('index_by_table.FIRST = '|| index_by_table.FIRST);
DBMS_OUTPUT.PUT_LINE('index_by_table.LAST = '|| index_by_table.LAST);
DBMS_OUTPUT.PUT_LINE('nested_table.PRIOR(2) = '|| nested_table.PRIOR(2));
DBMS_OUTPUT.PUT_LINE('nested_table.NEXT(2) = '|| nested_table.NEXT(2));
DBMS_OUTPUT.PUT_LINE('index_by_table.PRIOR(2) = '|| index_by_table.PRIOR(2));
DBMS_OUTPUT.PUT_LINE('index_by_table.NEXT(2) = '|| index_by_table.NEXT(2));
--Trim last two elements
nested_table.TRIM(2);
--Trim last element
nested_table.TRIM;
DBMS_OUTPUT.PUT_LINE('nested_table.LAST = '|| nested_table.LAST);
end;
3.变长数组
语法:
TYPE type_name IS {VARRAY | VARYING ARRAY } (size_limit) OF
element_type [NOT NULL] ;
varray_name type_name;
类似于嵌套表,当变长数组被声明时,自动设置为NULL。必须在引用单个元素之前,初始化变长数组。
不能对变长数组使用DELETE 方法来删除其元素。 可使用TRIM方法。
DECLARE
CURSOR name_cur IS SELECT last_name from student where rownum<=10;
TYPE last_name_type IS varray(10) of student.last_name%TYPE;
last_name_varray last_name_type :=last_name_type();
v_counter INTEGER := 0;
BEGIN
FOR name_rec in name_cur loop
v_counter := v_counter +1;
last_name_varray.EXTEND;
last_name_varray(v_counter) := name_rec.last_name ;
DBMS_OUTPUT.PUT_LINE('last_name ('|| v_counter || ') : '|| last_name_varray(v_counter));
END LOOP;
END;
declare
cursor city_cur is select city from zipcode where rownum <= 10;
Type city_type is varray(20) of zipcode.city%type;
city_varray city_type := city_type();
v_counter integer :=0;
begin
for city_rec in city_cur loop
v_counter := v_counter +1 ;
city_varray.extend;
city_varray(v_counter) := city_rec.city;
end loop;
for i in 1..v_counter loop
--extend the size of varray by 1 and copy the current element to the last element
city_varray.extend(1,i); --表示把第i位置上的元素复制一个放在数组后。
end loop;
for i in 1..20 loop
dbms_output.put_line('city_varray ('|| i || ') :'|| city_varray(i));
end loop;
end;
4. 多层集合
declare
type varray_type1 is varray(4) of integer;
type varray_type2 is varray(3) of varray_type1;
varray1 varray_type1 := varray_type1(2,4,6,8);
varray2 varray_type2 := varray_type2(varray1);
begin
dbms_output.put_line('Varray of integers');
for i in 1..4 loop
dbms_output.put_line('varray('|| i || '):' || varray1(i));
end loop;
varray2.extend;
varray2(2) := varray_type1(1,3,5,7);
dbms_output.put_line(chr(10) || ' Varray of varrays of integers');
for i in 1..2 loop
for j in 1..4 loop
dbms_output.put_line('varray2('|| i||')(' || j || '): ' || varray2(i)(j));
end loop;
end loop;
end;