8.pl/sql集合
處理單行單列數據,可以使用標量變量,處理單行多列的數據,可以使用PL/SQL記錄
處理單列多行數據,可以使用PL/SQL集合
PL/SQL集合類型類似於高級語言數組的一種複合數據類型
包括:索引表(PL/SQL表),嵌套表(NESTED TABLE),變長數組(VARRAY)三種
8.1 索引表:PL/SQL表 元素個數沒有限制,並且下標可以是負值
定義索引表:
- type type_name is table of element_type [not null] index by key_type;
- identifier type_name;
在索引表中使用BINARY_INTEGER和PLS_INTEGER
- set serveroutput on
- declare
- type ename_table_type is table of emp.ename%type index by binary_integer;
- ename_table ename_table_type;
- begin
- select ename into ename_table(-1) from emp where empno=&no;
- dbms_output.put_line('僱員名:'||ename_table(-1));
- end;
在索引表中使用VARCHAR
- set serveroutput on
- declare
- type area_table_type is table of number index by varchar2(10);
- area_table area_table_type;
- begin
- area_table('北京'):=1;
- area_table('上海'):=2;
- area_table('廣州'):=3;
- dbms_output.put_line('第一個元素:'||area_table.first);
- dbms_output.put_line('最後一個元素:'||area_table.last);
- end;
8.2 嵌套表:元素個數從1開始,並且元素個數沒有限制
定義嵌套表:
- type type_name is table of element_type;
- identifier type_name;
- declare
- type ename_table_type is table of emp.ename%type;
- ename_table ename_table_typeename_table_type:=ename_table_type('A','A');
在PL/SQL塊中使用嵌套表:使用嵌套表變量時,必須首先使用構造方法初始化嵌套表變量,然後才能在塊內引用嵌套表元素
- declare
- type ename_table_type is table of emp.ename%type;
- ename_table ename_table_type;
- begin
- ename_table:=ename_table_type('mary','mary','mary');
- dbms_output.put_line('僱員名:'|| ename_table(2));
- select ename into ename_table(2) from emp where empno=&no;
- dbms_output.put_line('僱員名:'||ename_table(2));
- end;
在表列中使用嵌套表:
在表列中使用嵌套表類型,必須首先使用CREATE TYPE命令建立嵌套表類型.
當使用嵌套表類型作爲表列的數據類型時,必須要爲嵌套表列指定專門的存儲表
- create type phone_type is table of varchar2(20);
- /
- create table employee(
- id number(4),name varchar2(10),sal number(6,2),
- phone phone_type
- )nested table phone store as phone_table;
8.3 在PL/SQL塊中爲嵌套表列插入數據
當定義嵌套表類型時,ORACLE自動爲該類型生成相應的構造方法.當爲嵌套表列插入數據時,需要使用嵌套表的構造方法
- begin
- insert into employee values(1,'scott',800,phone_type('0471-3456788','13804711111'));
- end;
在PL/SQL塊中檢索嵌套表列的數據
當在PL/SQL塊中檢索嵌套表列的數據時,需要定義嵌套表類型的變量接受其數據.
- set serveroutput on
- declare
- phone_table phone_type;
- begin
- select ename into phone_table from emp where empno=&no;
- for i in 1..phone_table.count loop
- dbms_output.put_line('電話:'||phone_table(i));
- end loop;
- end;
8.4 在pl/sql塊中更新嵌套表列的數據
更新嵌套表列的數據時,首先需要定義嵌套表變量,並使用構造方法初始化變量,然後纔可在執行部分使用UPDATE語句更新數據
- declare
- phone_table phone_typephone_type:=phone_type('0471-3456788','13804711111','0471-2233066','13056278568');
- begin
- update employee set phone=phone_talbe where id=1;
- end;
8.5變長數組(varray)
VARRAY也是一種用於處理PL/SQL數組的數據類型, 它也可以做爲表列的數據類型使用.
元素下標以1開始,並且元素的最大個數是有限制的
定義VARRAY的語法:
- type type_name is varray(size_limite) of element_type [not mull];
- identifier type_name;
當使用VARRAY元素時,必須要使用其構造方法初始化VARRAY元素.
- declare
- type ename_table_type is varray(20) of emp.ename%type;
- ename_talbe ename_table_typeename_table_type:=ename_table_type('A','A');
8.6 在PL/SQL塊中使用VARRAY
必須首先使用其構造方法來初始化VARRAY變量,然後才能在PL/SQL塊內引用VARRAY元素
- declare
- type ename_table_type is varray(20) of emp.ename%type;
- ename_table ename_table_typeename_table_type:=ename_table_type('mary');
- begin
- select ename into ename_table1) from emp where empno=&no;
- dbms_output.put_line('僱員名:'||ename_table(1));
- end;
在表列中使用varray
要在表列中引用該數據類型,則必須使用CREATE TYPE命令建立VARRAY類型
- create type phone_type is varray(20) of varchar2(20);
- /
- create table employee(
- id number(4),name varchar2(10),
- sal number(6,2),phone phone_type);
在PL/SQL塊中操縱VARRAY列的方法與操縱嵌套表列的方法完全相同.嵌套表列元素個數沒有限制,而VARRAY列的元素個數是有限制的.
PL/SQL記錄表
PL/SQL變量處理單行單列數據
PL/SQL記錄處理單行多列數據
PL/SQL集合處理多行單列數據
PL/SQL記錄表處理多行多列數據
8.7 PL/SQL記錄表結合了PL/SQL記錄和PL/SQL集合的優點
- declare
- type emp_table_type is table of emp%rowtype index by binary_integer;
- emp_table emp_table_type;
- begin
- select * into emp_table(1) from emp where empno=&no;
- dbms_output.put_line('僱員姓名:'||emp_table(1).ename);
- dbms_output.put_line('僱員姓名:'||emp_table(1).sal);
- end;
8.8 多級集合
多級集合是指嵌套了集合類型的集合類型
在PL/SQL塊中使用多級VARRAY:實現多維數組功能
定義二維VARRAY(10,10):
- declare
- type a1_varray_type is varray(10) of int;--定義一維VARRAY
- type na1_varray_type is varray(10) of a1_varray_type;--定義二維VARRAY集合
- --初始化二維集合變量
- nv1 nal_varray_typenal_varray_type:=nal_varray_type(
- a1_varray_type(58,100,102),
- a1_varray_type(55,6,73),
- a1_varray_type(2,4);
- )
- begin
- dbms_output.put_line('顯示二維數組所有元素');
- for i in 1..nv1.count loop
- for j in 1..nv1(i).count loop
- dbms_output.put_line('nvl('||i||','||j||')='||nvl(i)(j));
- end loop;
- end loop;
- end;
在PL/SQL塊中使用多級嵌套表
如果多維數組的元素個數沒有限制,那麼可以在嵌套表類型中嵌套另一個嵌套表類型
8.9 二維嵌套表
- declare
- type a1_table_type is table of int;--定義一維嵌套表
- type nal_table_type is table of a1_table_type;--定義二維嵌套表集合
- --初始化二維集合變量
- nvl nal_table_typenal_table_type:=nal_table_type(
- a1_table_type(2,4),
- a1_table_type(5,73));
- begin
- dbms_output.put_line('顯示二維數組所有元素');
- for i in 1..nvl.count loop
- for j in 1..nvl(i).count loop
- dbms_output.put_line('nvl('||i||','||j||')='||nvl(i)(j));
- end loop;
- end loop;
- end;
在PL/SQL塊中使用多級索引表
二維索引表:
- declare
- type a1_table_type is table of int index by binary_integer;
- type nal_table_type is table of al_table_type index by binary_integer;
- nvl nal_table_type;
- begin
- nvl(1)(1):=10;
- nvl(1)(2):=5;
- nvl(2)(1):=100;
- nvl(2)(2):=50;
- dbms_output.put_line('顯示二維數組所有元素');
- for i in 1..nvl.count loop
- for j in 1..nvl(i).count loop
- dbms_output.put_line('nvl('||i||','||j||')='||nvl(i)(j));
- end loop;
- end loop;
- end;
8.10集合方法:ORACLE提供的用於操縱集合變量的內置函數或過程,其中EXISTS,COUNT,LIMIT,FIRST,NEXT,FRIOR和NEXT是函數
而EXTEND,TRIM和DELETE則是過程
集合方法只能在PL/SQL語句中使用,不能在SQL語句中使用.
集合方法EXTEND和TRIM只適用於嵌套表和VARRAY,而不適合於索引表
1.EXISTS:用於確定集合元素是否存在
- declare
- type ename_table_type is table of emp.ename%type;
- ename_table ename_table_typeename_table_type:=ename_table_type('A','A');
- begin
- if ename_table.exists(1) then
- ename_table(1):='SCOTT';
- dbms_output.put_line(ename_table(1) );
- else
- dbms_output.put_line('必須初始化集合元素');
- end if;
- end;
2.COUNT:用於返回當前集合變量中的元素總個數.
- declare
- type ename_table_type is table of emp.ename%type index by binary_integer;
- ename_table ename_table_type;
- begin
- ename_table(-5):='scott';
- ename_table(1):='smith';
- ename_table(5):='mary';
- ename_table(10):='blake';
- dbms_output.put_line('集合元素總個數:'||ename_table.count);
- end;
3.LIMIT:用於返回集合元素的最大個數.因爲嵌套表和索引表的餘數個數沒有限制,返回NULL
對於VARRAY來說,該方法返回VARRAY所允許的最大元素個數
- declare
- type ename_table_type is varray(20) of emp.ename%type;
- ename_table ename_table_typeename_table_type:=ename_table_type('mary');
- begin
- dbms_output.put_line('集合元素的最大個數:'||ename_table.limit);
- end;
4.FIRST和LAST:FIRST用於返回集合變量第一個元素的下標,而LAST方法則用於返回集合變量最後一個元素的下
- declare
- type ename_table_type is table of emp.ename%type index by binary_integer;
- ename_table ename_table_type;
- begin
- ename_table(-5):='scott';
- ename_table(1):='smith';
- ename_table(5):='mary';
- ename_table(10):='blake';
- dbms_output.put_line('第一個元素:'||ename_table.first);
- dbms_output.put_line('第一個元素:'||ename_table(-5));
- dbms_output.put_line('最後一個元素:'||ename_table.last);
- end;
5.FRIOR和NEXT:PRIOR返回當前集合元素的前一個元素的下標,而NEXT方法則用於返回當前集合元素的後一個元素的下標
- declare
- type ename_table_type is table of emp.ename%type index by binary_integer;
- ename_table ename_table_type;
- begin
- ename_table(-5):='scott';
- ename_table(1):='smith';
- ename_table(5):='mary';
- ename_table(10):='blake';
- dbms_output.put_line('元素5的前一個元素:'||ename_table.prior(5));
- dbms_output.put_line('元素5的後一個元素:'||ename_table.next(5));
- end;
6.EXTEND:用於擴展集合變量的尺寸,併爲它們增加元素.只適用於嵌套表和VARRAY.
三種調用格式:EXTEND,EXTEND(N),EXTEND(N,I):添加N個元素,值與第I個元素相同
- declare
- type ename_table_type is varray(20) of varchar2(10);
- ename_table ename_table_type;
- begin
- ename_table:=ename_table_type('mary');
- ename_table.extend(5,1);
- dbms_output.put_line('元素個數:'||ename_table.count);
- end;
7.TRIM:用於從集合尾部刪除元素,有TRIM和TRIM(N)兩種調用格式.
只適用於嵌套表和VARRAY
- declare
- type ename_table_type is table of varchar2(10);
- ename_table ename_table_type;
- begin
- ename_table:=ename_table_type('a','a','a','a','a');
- ename_table.trim(5);
- dbms_output.put_line('元素個數:'||ename_table.count);
- end;
8.DELETE:刪除結合元素,但該方法只適用於嵌套表和索引表,不適用於VARRAY.
有DELETE,DELETE(N),DELETE(M,N)三種調用方式.
DETELE(M,N)刪除集合變量從M到N之間的所有元素
- declare
- type ename_table_type is table of emp.ename%type index by binary_integer;
- ename_table ename_table_type;
- begin
- ename_table(-5):='scott';
- ename_table(1):='smith';
- ename_table(5):='mary';
- ename_table(10):='blake';
- ename_table.delete(1);
- if ename_table. exists(5) then dbms_output.put_line('success');
- else
- dbms_output.put_line('元素總個數:'||ename_table.count);
- end if;
- end;
8.11集合賦值
使用嵌套表和VARRAY時,通過執行INSERT,UPDATE,FETCH,SELECT賦值語句,可以將一個集合的數據賦值給另一個集合.
當給嵌套表賦值時,還可以使用SET,MULTISET UNION,MULTISET INTERSECT,MULTISET EXCEPT等集合操作符
SET:用於取消嵌套表中的重複值.
MULTISET UNION:取得兩個嵌套表的並集(DISTINCT)
MULTISET INTERSECT:用於取得兩個嵌套表的交集.
NULTISET EXCEPT:用於取得兩個嵌套表的差集
1.將一個集合的數據賦值個另一個集合
源集合和目標集合的數據類型必須完全一致.
- declare
- type name_array_type is varray(4) of varchar2(10);
- name_array1 name_array_type;
- name_array2 name_array_type;
- begin
- name_array1:=name_array_type('scott','smith');
- name_array2:=name_array_type('a','a','a','a');
- dbms_output.put_line('name_array2的原數據:');
- for i in 1..name_array2.count loop
- dbms_output.put_line(' '||name_array2(i));
- end loop;
- dbms_output.new_line;
- name_array2:=name_array1;
- dbms_output.put('name_array2的新數據:');
- for i in 1..name_array2.count loop
- dbms_output.put(' '||name_array2(i));
- end loop;
- dbms_output.new_line;
- end;
2.給集合賦NULL值:清空集合變量的所有數據(集合方法DETELE,TRIM也可以)
- declare
- type name_varray_type is varray(4) of varchar2(10);
- name_array name_varray_type;
- name_empty name_varray_type;
- begin
- name_array:=name_varray_type('scott','smith');
- dbms_output.put_line('name_array的原有元素個數:'||name_array.count);
- name_array:=name_empty;
- if name_array is null then
- dbms_output.put_line('name_array的現有元素個數:0');
- end if;
- end;
3.使用集合操作符給嵌套表賦值
1.使用SET操作符:用於取消特定嵌套表中的重複值.
- declare
- type nt_table_type is table of number;
- nt_table nt_table_typent_table_type:=nt_table_type(2,4,3,1,2);
- result nt_table_type;
- begin
- result:=set(nt_table);
- dbms_output.put('result:');
- for i in 1..result.count loop
- dbms_output.put(' '||result(i));
- end loop;
- dbms_output.new_line;
- end;
2.使用MULTISET UNION操作符:取得兩個嵌套表的並集.結果集中會包含重複值
- declare
- type nt_table_type is table of number;
- nt1 nt_table_typent_table_type:=nt_table_type(1,2,3);
- nt2 nt_table_typent_table_type:=nt_table_type(3,4,5);
- result nt_table_type;
- begin
- result:=nt1 multiset union nt2;
- dbms_output.put('result:');
- for i in 1..result.count loop
- dbms_output.put(' '||result(i));
- end loop;
- dbms_output.new_line;
- end;
3.使用MULTISET UNION DISTINCT操作符:用於取得兩個嵌套表的並集,並取消重複結果.
- declare
- type nt_table_type is table of number;
- nt1 nt_table_typent_table_type:=nt_table_type(1,2,3);
- nt2 nt_table_typent_table_type:=nt_table_type(3,4,5);
- result nt_table_type;
- begin
- result:=nt1 multiset union distinct nt2;
- dbms_output.put('result:');
- for i in 1..result.count loop
- dbms_output.put(' '||result(i));
- end loop;
- dbms_output.new_line;
- end;
4.使用MULTISET INTERSECT操作符:用於取得兩個嵌套表的交集
- declare
- type nt_table_type is table of number;
- nt1 nt_table_typent_table_type:=nt_table_type(1,2,3);
- nt2 nt_table_typent_table_type:=nt_table_type(3,4,5);
- result nt_table_type;
- begin
- result:=nt1 multiset intersect nt2;
- dbms_output.put('result:');
- for i in 1..result.count loop
- dbms_output.put(' '||result(i));
- end loop;
- dbms_output.new_line;
- end;
5.使用MULTISET EXCEPT操作符:取得兩個嵌套表的差集.在NT1中存在,但在NT2中不存在
- declare
- type nt_table_type is table of number;
- nt1 nt_table_typent_table_type:=nt_table_type(1,2,3);
- nt2 nt_table_typent_table_type:=nt_table_type(3,4,5);
- result nt_table_type;
- begin
- result:=nt1 multiset except nt2;
- dbms_output.put('result:');
- for i in 1..result.count loop
- dbms_output.put(' '||result(i));
- end loop;
- dbms_output.new_line;
- end;