PL/SQL入門--複合類型及集合(2)

 8.pl/sql集合

  處理單行單列數據,可以使用標量變量,處理單行多列的數據,可以使用PL/SQL記錄

  處理單列多行數據,可以使用PL/SQL集合

  PL/SQL集合類型類似於高級語言數組的一種複合數據類型

  包括:索引表(PL/SQL),嵌套表(NESTED TABLE),變長數組(VARRAY)三種

  8.1 索引表:PL/SQL表 元素個數沒有限制,並且下標可以是負值

  定義索引表:

  1. type type_name is table of element_type [not null] index by key_type; 
  2.  
  3. identifier type_name; 

  在索引表中使用BINARY_INTEGERPLS_INTEGER

 

  1. set serveroutput on 
  2.  
  3. declare 
  4.  
  5.   type ename_table_type is table of emp.ename%type index by binary_integer; 
  6.  
  7.   ename_table ename_table_type; 
  8.  
  9. begin 
  10.  
  11.   select ename into ename_table(-1) from emp where empno=&no; 
  12.  
  13.   dbms_output.put_line('僱員名:'||ename_table(-1)); 
  14.  
  15. end;  

 

  在索引表中使用VARCHAR

  1. set serveroutput on 
  2.  
  3.  declare 
  4.  
  5.    type area_table_type is table of number index by varchar2(10); 
  6.  
  7.    area_table area_table_type; 
  8.  
  9.  begin 
  10.  
  11.    area_table('北京'):=1
  12.  
  13.    area_table('上海'):=2
  14.  
  15.    area_table('廣州'):=3
  16.  
  17.    dbms_output.put_line('第一個元素:'||area_table.first); 
  18.  
  19.    dbms_output.put_line('最後一個元素:'||area_table.last); 
  20.  
  21.  end; 

  8.2 嵌套表:元素個數從1開始,並且元素個數沒有限制

  定義嵌套表:

  1. type type_name is table of element_type; 
  2.  
  3. identifier type_name; 
  4.  
  5.    
  6.  
  7.       declare 
  8.  
  9.         type ename_table_type is table of emp.ename%type; 
  10.  
  11.         ename_table ename_table_typeename_table_type:=ename_table_type('A','A'); 

  PL/SQL塊中使用嵌套表:使用嵌套表變量時,必須首先使用構造方法初始化嵌套表變量,然後才能在塊內引用嵌套表元素

  1. declare 
  2.  
  3.     type ename_table_type is table of emp.ename%type; 
  4.  
  5.     ename_table ename_table_type; 
  6.  
  7.   begin 
  8.  
  9. ename_table:=ename_table_type('mary','mary','mary'); 
  10.  
  11. dbms_output.put_line('僱員名:'|| ename_table(2)); 
  12.  
  13.     select ename into ename_table(2) from emp where empno=&no; 
  14.  
  15.     dbms_output.put_line('僱員名:'||ename_table(2)); 
  16.  
  17.   end; 

  在表列中使用嵌套表:

  在表列中使用嵌套表類型,必須首先使用CREATE TYPE命令建立嵌套表類型.

  當使用嵌套表類型作爲表列的數據類型時,必須要爲嵌套表列指定專門的存儲表

  1. create type phone_type is table of varchar2(20); 
  2.  
  3.  /
  1. create table employee( 
  2.  
  3.     id number(4),name varchar2(10),sal number(6,2), 
  4.  
  5.     phone phone_type 
  6.  
  7.  )nested table phone store as phone_table; 

  8.3 PL/SQL塊中爲嵌套表列插入數據

  當定義嵌套表類型時,ORACLE自動爲該類型生成相應的構造方法.當爲嵌套表列插入數據時,需要使用嵌套表的構造方法

 

  1. begin 
  2.  
  3.   insert into employee values(1,'scott',800,phone_type('0471-3456788','13804711111')); 
  4.  
  5. end;  

 

  PL/SQL塊中檢索嵌套表列的數據

  當在PL/SQL塊中檢索嵌套表列的數據時,需要定義嵌套表類型的變量接受其數據.

  1. set serveroutput on 
  2.  
  3.  declare 
  4.  
  5.    phone_table phone_type; 
  6.  
  7.  begin 
  8.  
  9.    select ename into phone_table from emp where empno=&no; 
  10.  
  11.    for i in 1..phone_table.count loop 
  12.  
  13.    dbms_output.put_line('電話:'||phone_table(i)); 
  14.  
  15.    end loop; 
  16.  
  17.  end; 

  8.4 pl/sql塊中更新嵌套表列的數據

  更新嵌套表列的數據時,首先需要定義嵌套表變量,並使用構造方法初始化變量,然後纔可在執行部分使用UPDATE語句更新數據

  1. declare 
  2.  
  3.     phone_table phone_typephone_type:=phone_type('0471-3456788','13804711111','0471-2233066','13056278568'); 
  4.  
  5.   begin 
  6.  
  7.     update employee set phone=phone_talbe where id=1
  8.  
  9.   end; 

  8.5變長數組(varray)

  VARRAY也是一種用於處理PL/SQL數組的數據類型, 它也可以做爲表列的數據類型使用.

  元素下標以1開始,並且元素的最大個數是有限制的

  定義VARRAY的語法:

  

  1. type type_name is varray(size_limite) of element_type [not mull]; 
  2.  
  3. identifier type_name; 

  當使用VARRAY元素時,必須要使用其構造方法初始化VARRAY元素.

  1. declare 
  2.  
  3.     type ename_table_type is varray(20) of emp.ename%type; 
  4.  
  5.     ename_talbe ename_table_typeename_table_type:=ename_table_type('A','A'); 

  8.6 PL/SQL塊中使用VARRAY

  必須首先使用其構造方法來初始化VARRAY變量,然後才能在PL/SQL塊內引用VARRAY元素

 

  1. declare 
  2.  
  3.   type ename_table_type is varray(20) of emp.ename%type; 
  4.  
  5.   ename_table ename_table_typeename_table_type:=ename_table_type('mary'); 
  6.  
  7. begin 
  8.  
  9.   select ename into ename_table1) from emp where empno=&no; 
  10.  
  11.   dbms_output.put_line('僱員名:'||ename_table(1)); 
  12.  
  13. end;  

 

  在表列中使用varray

  要在表列中引用該數據類型,則必須使用CREATE TYPE命令建立VARRAY類型

  1. create type phone_type is varray(20) of varchar2(20); 
  2.  
  3.   / 

 

  1. create table employee( 
  2.  
  3.     id number(4),name varchar2(10), 
  4.  
  5.     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集合的優點

  1. declare 
  2.  
  3.     type emp_table_type is table of emp%rowtype index by binary_integer; 
  4.  
  5.     emp_table emp_table_type; 
  6.  
  7.   begin 
  8.  
  9.     select * into emp_table(1) from emp where empno=&no; 
  10.  
  11.     dbms_output.put_line('僱員姓名:'||emp_table(1).ename); 
  12.  
  13.     dbms_output.put_line('僱員姓名:'||emp_table(1).sal); 
  14.  
  15.   end; 

  8.8 多級集合

  多級集合是指嵌套了集合類型的集合類型

 

  PL/SQL塊中使用多級VARRAY:實現多維數組功能

  定義二維VARRAY(10,10):

 

  1.   declare 
  2.  
  3.     type a1_varray_type is varray(10) of int;--定義一維VARRAY 
  4.  
  5.     type na1_varray_type is varray(10) of a1_varray_type;--定義二維VARRAY集合 
  6.  
  7.     --初始化二維集合變量 
  8.  
  9.     nv1 nal_varray_typenal_varray_type:=nal_varray_type( 
  10.  
  11.         a1_varray_type(58,100,102), 
  12.  
  13.         a1_varray_type(55,6,73), 
  14.  
  15.         a1_varray_type(2,4); 
  16.  
  17. ) 
  18.  
  19.     begin 
  20.  
  21.       dbms_output.put_line('顯示二維數組所有元素'); 
  22.  
  23.       for i in 1..nv1.count loop 
  24.  
  25.           for j in 1..nv1(i).count loop 
  26.  
  27.               dbms_output.put_line('nvl('||i||','||j||')='||nvl(i)(j)); 
  28.  
  29.           end loop; 
  30.  
  31.       end loop; 
  32.  
  33.    end;  

 

  PL/SQL塊中使用多級嵌套表

  如果多維數組的元素個數沒有限制,那麼可以在嵌套表類型中嵌套另一個嵌套表類型

  8.9 二維嵌套表

  1. declare 
  2.  
  3.     type a1_table_type is table of int;--定義一維嵌套表 
  4.  
  5.     type nal_table_type is table of a1_table_type;--定義二維嵌套表集合 
  6.  
  7.     --初始化二維集合變量 
  8.  
  9.     nvl nal_table_typenal_table_type:=nal_table_type( 
  10.  
  11.         a1_table_type(2,4), 
  12.  
  13.         a1_table_type(5,73)); 
  14.  
  15.   begin 
  16.  
  17.     dbms_output.put_line('顯示二維數組所有元素'); 
  18.  
  19.     for i in 1..nvl.count loop 
  20.  
  21.        for j in 1..nvl(i).count loop 
  22.  
  23.            dbms_output.put_line('nvl('||i||','||j||')='||nvl(i)(j)); 
  24.  
  25.        end loop; 
  26.  
  27.     end loop; 
  28.  
  29.   end; 

  PL/SQL塊中使用多級索引表

  二維索引表:

  1. declare 
  2.  
  3.    type a1_table_type is table of int index by binary_integer; 
  4.  
  5.    type nal_table_type is table of al_table_type index by binary_integer; 
  6.  
  7.    nvl nal_table_type; 
  8.  
  9.  begin 
  10.  
  11.    nvl(1)(1):=10
  12.  
  13.    nvl(1)(2):=5
  14.  
  15.    nvl(2)(1):=100
  16.  
  17.    nvl(2)(2):=50
  18.  
  19.    dbms_output.put_line('顯示二維數組所有元素'); 
  20.  
  21.    for i in 1..nvl.count loop 
  22.  
  23.       for j in 1..nvl(i).count loop 
  24.  
  25.          dbms_output.put_line('nvl('||i||','||j||')='||nvl(i)(j)); 
  26.  
  27.       end loop; 
  28.  
  29.    end loop; 
  30.  
  31.  end; 

  8.10集合方法:ORACLE提供的用於操縱集合變量的內置函數或過程,其中EXISTS,COUNT,LIMIT,FIRST,NEXT,FRIORNEXT是函數

  EXTEND,TRIMDELETE則是過程

  集合方法只能在PL/SQL語句中使用,不能在SQL語句中使用.

  集合方法EXTENDTRIM只適用於嵌套表和VARRAY,而不適合於索引表

  1.EXISTS:用於確定集合元素是否存在

  1. declare 
  2.  
  3.     type ename_table_type is table of emp.ename%type; 
  4.  
  5.     ename_table ename_table_typeename_table_type:=ename_table_type('A','A'); 
  6.  
  7.   begin 
  8.  
  9.     if ename_table.exists(1) then 
  10.  
  11.        ename_table(1):='SCOTT'
  12.  
  13.        dbms_output.put_line(ename_table(1) ); 
  14.  
  15.     else 
  16.  
  17.        dbms_output.put_line('必須初始化集合元素'); 
  18.  
  19.     end if; 
  20.  
  21.   end; 

  2.COUNT:用於返回當前集合變量中的元素總個數.

  1. declare 
  2.  
  3.    type ename_table_type is table of emp.ename%type index by binary_integer; 
  4.  
  5.    ename_table ename_table_type; 
  6.  
  7.  begin 
  8.  
  9.    ename_table(-5):='scott'
  10.  
  11.    ename_table(1):='smith'
  12.  
  13.    ename_table(5):='mary'
  14.  
  15.    ename_table(10):='blake'
  16.  
  17.    dbms_output.put_line('集合元素總個數:'||ename_table.count); 
  18.  
  19.  end; 

  3.LIMIT:用於返回集合元素的最大個數.因爲嵌套表和索引表的餘數個數沒有限制,返回NULL

  對於VARRAY來說,該方法返回VARRAY所允許的最大元素個數

  1. declare 
  2.  
  3.     type ename_table_type is varray(20) of emp.ename%type; 
  4.  
  5.     ename_table ename_table_typeename_table_type:=ename_table_type('mary'); 
  6.  
  7.   begin 
  8.  
  9.     dbms_output.put_line('集合元素的最大個數:'||ename_table.limit); 
  10.  
  11.   end; 

 

  4.FIRSTLAST:FIRST用於返回集合變量第一個元素的下標,LAST方法則用於返回集合變量最後一個元素的下

  1. declare 
  2.  
  3.     type ename_table_type is table of emp.ename%type index by binary_integer; 
  4.  
  5.     ename_table ename_table_type; 
  6.  
  7.   begin 
  8.  
  9.     ename_table(-5):='scott'
  10.  
  11.     ename_table(1):='smith'
  12.  
  13.     ename_table(5):='mary'
  14.  
  15.     ename_table(10):='blake'
  16.  
  17. dbms_output.put_line('第一個元素:'||ename_table.first); 
  18.  
  19. dbms_output.put_line('第一個元素:'||ename_table(-5)); 
  20.  
  21.     dbms_output.put_line('最後一個元素:'||ename_table.last); 
  22.  
  23.   end; 

  5.FRIORNEXT:PRIOR返回當前集合元素的前一個元素的下標,NEXT方法則用於返回當前集合元素的後一個元素的下標

  1. declare 
  2.  
  3.    type ename_table_type is table of emp.ename%type index by binary_integer; 
  4.  
  5.    ename_table ename_table_type; 
  6.  
  7.  begin 
  8.  
  9.    ename_table(-5):='scott'
  10.  
  11.    ename_table(1):='smith'
  12.  
  13.    ename_table(5):='mary'
  14.  
  15.    ename_table(10):='blake'
  16.  
  17.    dbms_output.put_line('元素5的前一個元素:'||ename_table.prior(5)); 
  18.  
  19.    dbms_output.put_line('元素5的後一個元素:'||ename_table.next(5)); 
  20.  
  21.  end; 

  6.EXTEND:用於擴展集合變量的尺寸,併爲它們增加元素.只適用於嵌套表和VARRAY.

         三種調用格式:EXTEND,EXTEND(N),EXTEND(N,I):添加N個元素,值與第I個元素相同

  1. declare 
  2.  
  3.    type ename_table_type is varray(20) of varchar2(10); 
  4.  
  5.    ename_table ename_table_type; 
  6.  
  7.  begin 
  8.  
  9.    ename_table:=ename_table_type('mary'); 
  10.  
  11.    ename_table.extend(5,1); 
  12.  
  13.    dbms_output.put_line('元素個數:'||ename_table.count); 
  14.  
  15.  end; 

  7.TRIM:用於從集合尾部刪除元素,TRIMTRIM(N)兩種調用格式.

    只適用於嵌套表和VARRAY

  1. declare 
  2.  
  3.     type ename_table_type is table of varchar2(10); 
  4.  
  5.     ename_table ename_table_type; 
  6.  
  7.   begin 
  8.  
  9.     ename_table:=ename_table_type('a','a','a','a','a'); 
  10.  
  11.     ename_table.trim(5); 
  12.  
  13.     dbms_output.put_line('元素個數:'||ename_table.count); 
  14.  
  15.   end; 

  8.DELETE:刪除結合元素,但該方法只適用於嵌套表和索引表,不適用於VARRAY.

         DELETE,DELETE(N),DELETE(M,N)三種調用方式.

         DETELE(M,N)刪除集合變量從MN之間的所有元素

 

  1.   declare 
  2.  
  3.     type ename_table_type is table of emp.ename%type index by binary_integer; 
  4.  
  5.     ename_table ename_table_type; 
  6.  
  7.   begin 
  8.  
  9.     ename_table(-5):='scott'
  10.  
  11.     ename_table(1):='smith'
  12.  
  13.     ename_table(5):='mary'
  14.  
  15.     ename_table(10):='blake'
  16.  
  17. ename_table.delete(1); 
  18.  
  19. if ename_table. exists(5) then  dbms_output.put_line('success'); 
  20.  
  21. else 
  22.  
  23. dbms_output.put_line('元素總個數:'||ename_table.count); 
  24.  
  25. end if; 
  26.  
  27.   end; 

 

 

  8.11集合賦值

  使用嵌套表和VARRAY,通過執行INSERT,UPDATE,FETCH,SELECT賦值語句,可以將一個集合的數據賦值給另一個集合.

  當給嵌套表賦值時,還可以使用SET,MULTISET UNION,MULTISET INTERSECT,MULTISET EXCEPT等集合操作符

  SET:用於取消嵌套表中的重複值.

  MULTISET UNION:取得兩個嵌套表的並集(DISTINCT)

  MULTISET INTERSECT:用於取得兩個嵌套表的交集.

  NULTISET EXCEPT:用於取得兩個嵌套表的差集

  1.將一個集合的數據賦值個另一個集合

    源集合和目標集合的數據類型必須完全一致.

  1. declare 
  2.  
  3.    type name_array_type is varray(4) of varchar2(10); 
  4.  
  5.    name_array1 name_array_type; 
  6.  
  7.    name_array2 name_array_type; 
  8.  
  9.  begin 
  10.  
  11.    name_array1:=name_array_type('scott','smith'); 
  12.  
  13.    name_array2:=name_array_type('a','a','a','a'); 
  14.  
  15.    dbms_output.put_line('name_array2的原數據:'); 
  16.  
  17.    for i in 1..name_array2.count loop 
  18.  
  19.       dbms_output.put_line(' '||name_array2(i)); 
  20.  
  21.    end loop; 
  22.  
  23.    dbms_output.new_line; 
  24.  
  25.    name_array2:=name_array1
  26.  
  27.    dbms_output.put('name_array2的新數據:'); 
  28.  
  29.    for i in 1..name_array2.count loop 
  30.  
  31.       dbms_output.put(' '||name_array2(i)); 
  32.  
  33.    end loop; 
  34.  
  35.    dbms_output.new_line; 
  36.  
  37.  end; 

 

  2.給集合賦NULL:清空集合變量的所有數據(集合方法DETELE,TRIM也可以)

  1. declare 
  2.  
  3.    type name_varray_type is varray(4) of varchar2(10); 
  4.  
  5.    name_array name_varray_type; 
  6.  
  7.    name_empty name_varray_type; 
  8.  
  9.  begin 
  10.  
  11.    name_array:=name_varray_type('scott','smith'); 
  12.  
  13.    dbms_output.put_line('name_array的原有元素個數:'||name_array.count); 
  14.  
  15.    name_array:=name_empty
  16.  
  17.    if name_array is null then      
  18.  
  19.       dbms_output.put_line('name_array的現有元素個數:0'); 
  20.  
  21.    end if; 
  22.  
  23.  end; 

 

  3.使用集合操作符給嵌套表賦值

    1.使用SET操作符:用於取消特定嵌套表中的重複值.

  1. declare 
  2.  
  3.    type nt_table_type is table of number; 
  4.  
  5.    nt_table nt_table_typent_table_type:=nt_table_type(2,4,3,1,2); 
  6.  
  7.    result nt_table_type; 
  8.  
  9.  begin 
  10.  
  11.    result:=set(nt_table); 
  12.  
  13.    dbms_output.put('result:'); 
  14.  
  15.    for i in 1..result.count loop 
  16.  
  17.      dbms_output.put(' '||result(i)); 
  18.  
  19.    end loop; 
  20.  
  21.    dbms_output.new_line; 
  22.  
  23.  end; 

 

    2.使用MULTISET UNION操作符:取得兩個嵌套表的並集.結果集中會包含重複值

 

  1. declare 
  2.  
  3.   type nt_table_type is table of number; 
  4.  
  5.   nt1 nt_table_typent_table_type:=nt_table_type(1,2,3); 
  6.  
  7.   nt2 nt_table_typent_table_type:=nt_table_type(3,4,5); 
  8.  
  9.   result nt_table_type; 
  10.  
  11. begin 
  12.  
  13.   result:=nt1 multiset union nt2; 
  14.  
  15.   dbms_output.put('result:'); 
  16.  
  17.   for i in 1..result.count loop 
  18.  
  19.     dbms_output.put(' '||result(i)); 
  20.  
  21.   end loop; 
  22.  
  23.   dbms_output.new_line; 
  24.  
  25. end; 

 

  3.使用MULTISET UNION DISTINCT操作符:用於取得兩個嵌套表的並集,並取消重複結果.

  1. declare 
  2.  
  3.     type nt_table_type is table of number; 
  4.  
  5.     nt1 nt_table_typent_table_type:=nt_table_type(1,2,3); 
  6.  
  7.     nt2 nt_table_typent_table_type:=nt_table_type(3,4,5); 
  8.  
  9.     result nt_table_type; 
  10.  
  11.   begin 
  12.  
  13.     result:=nt1 multiset union distinct nt2; 
  14.  
  15.     dbms_output.put('result:'); 
  16.  
  17.     for i in 1..result.count loop 
  18.  
  19.       dbms_output.put(' '||result(i)); 
  20.  
  21.     end loop; 
  22.  
  23.     dbms_output.new_line; 
  24.  
  25.   end;

  4.使用MULTISET INTERSECT操作符:用於取得兩個嵌套表的交集

  1. declare 
  2.  
  3.     type nt_table_type is table of number; 
  4.  
  5.     nt1 nt_table_typent_table_type:=nt_table_type(1,2,3); 
  6.  
  7.     nt2 nt_table_typent_table_type:=nt_table_type(3,4,5); 
  8.  
  9.     result nt_table_type; 
  10.  
  11.   begin 
  12.  
  13.     result:=nt1 multiset intersect nt2; 
  14.  
  15.     dbms_output.put('result:'); 
  16.  
  17.     for i in 1..result.count loop 
  18.  
  19.       dbms_output.put(' '||result(i)); 
  20.  
  21.     end loop; 
  22.  
  23.     dbms_output.new_line; 
  24.  
  25.   end;

  5.使用MULTISET EXCEPT操作符:取得兩個嵌套表的差集.NT1中存在,但在NT2中不存在

  1. declare 
  2.  
  3.    type nt_table_type is table of number; 
  4.  
  5.    nt1 nt_table_typent_table_type:=nt_table_type(1,2,3); 
  6.  
  7.    nt2 nt_table_typent_table_type:=nt_table_type(3,4,5); 
  8.  
  9.    result nt_table_type; 
  10.  
  11.  begin 
  12.  
  13.    result:=nt1 multiset except nt2; 
  14.  
  15.    dbms_output.put('result:'); 
  16.  
  17.    for i in 1..result.count loop 
  18.  
  19.       dbms_output.put(' '||result(i)); 
  20.  
  21.    end loop; 
  22.  
  23.    dbms_output.new_line; 
  24.  
  25.  end; 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章