oracle 三種集合數據類型【varray,嵌套表,聯合數組】+record

         在oracle 11.2中,oracle總共提供了三種集合類型:varray,嵌套表,聯合數組。所謂集合,簡單來說就是保存多行數據的數據類型,相當於保存在內存中的小型表,便於暫時保存數據,以及數據的重複使用。下面的表簡單描述了其中的區別與聯繫:

類型
保存數據類型數量
長度
創建實例
標量集合
varry
一種
固定長度(長度使用extend方法增加)
一維數組(相當於類,有其方法和構造方法【類型名】)
序號連續
對象類型
create or replace type type_name as varry(3) of varchar(20)或者在程序的定義區中聲明:
type type_name is varry(3) of varchar(20);
初始化:object_name type_name :=type_name();
賦值: object_name(i):=n;
標量集合
嵌套表
一種
長度沒有限制
一維數組(相當於類,有其方法和構造方法【類型名】)
序號連續
對象類型
create or replace type type_name as table of varchar(20)或者在程序的定義區中聲明:
type type_name is table of varchar(20)
初始化:object_name type_name :=type_name();
賦值: object_name type_name :=type_name();
標量集合
關聯數組
一種
長度沒有限制
一維列表
序號不連續,刪除會斷續
非對象類型,只能用於PL/SQL
只能在程序的定義區中聲明:
type type_name is table of varchar(20)index by binary_integer
初始化:object_name type_name;
賦值: object_name:=n;
對象類型集合
SQL嵌套表
多種
長度沒有限制
列表(跟table很像)
多維數組
SQL記錄集合
1、創建對象類型
create or replace type object_type_name is object
(
column_name number,
column_name char
);
2、創建SQL級別的對象類型集合
create or replace type object_type_name_table is table of object_type_name;
3、初始化
object_name object_type_name_table :=object_type_name_table ();
4、賦值
object_name(i):=object_type_name (i,i,i);
對象類型集合
PL/SQL嵌套表
多種
長度沒有限制
列表(跟table很像)
多維數組
SQL記錄集合
1、3、4同上
2、創建PL/SQL級別的對象類型集合:聲明
type object_type_name_table is table of object_type_name
對象類型集合
記錄類型集合
多種
一行數據
相當於數據庫表中的一行數據
非對象類型
(只能在PL/SQL中使用)
1、聲明(在一個包中創建)
type recorde_name is record
(
column_name number,
column_name char
);
type object_recorde_name is table of recorde_name index by PLS_INTEGER;
2、初始化
object_name object_recorde_name;
3、賦值
object_name(i)=i;

1、varray固定數組

     簡單來說,varray就是一維數組,保存一種數據類型的數據,長度固定。聲明的時候若爲空數組,則表示還沒有分配空間,需要手工分配空間extend,否則會報錯。另外需要注意的是,該數組的下標是從1開始的。

set serveroutput on;
declare
no int :=1;
type fixed_array is varray(4) of char(2);---varray固定數組類型定義;
Farray fixed_array :=fixed_array();---varray固定數組聲明,這裏定義的數組爲空數組,並沒有分配任何空間
begin
for i in (select distinct COUNTRY_ISO_CODE from countries where rownum<4)loop
    farray.extend;---分配空間,不能訪問空數組,所以空數組的場合,必須進行數組擴展
    farray(no):=i.COUNTRY_ISO_CODE;---下標從1開始,不能超過數組所有元素的總和,當下標超出允許範圍時,出現異常:ORA-06532: Subscript outside of limit
    no := no+1;
end loop;
dbms_output.put_line('分配的空間:'|| farray.count);---count這個API方法是輸出所分配的空間;
for i in 1..farray.count loop   ----輸出結果值;
    dbms_output.put('/'||farray(i));
    if i=farray.count then
    dbms_output.new_line;
    end if;
end loop;
end;

anonymous block completed
分配的空間:3
/US/DE/GB

2、可變數組

     顧名思義,就是數組的長度沒有限制。其中有兩種集合類型,一是嵌套表,二是聯合數組。跟上面的varray一樣,數組的下標從1開始。不過,聯合數組的序號有可能是不連續的,刪除了其中的某個元素之後就不連續了。

/**嵌套表作爲標量集合的時候,跟上面的varray差不多。
 **聲明是若爲空數組,則需要分配空間;
 **不同的是,分配的空間沒有限制
 **/
set serveroutput on;
declare
no int :=1;
type variable_array is table of char(2);--沒有空間分配的限定設置
vtable variable_array :=variable_array();
begin
for i in (select distinct COUNTRY_ISO_CODE from countries where rownum<5)loop
    vtable.extend;            --分配空間     
    vtable(no):=i.COUNTRY_ISO_CODE;
    no := no+1;
end loop;
dbms_output.put_line('分配的空間:'|| vtable.count);---可以看到結果爲4
for i in 1..vtable.count loop   
    dbms_output.put('/'||vtable(i));
    if i=vtable.count then
    dbms_output.new_line;
    end if;
end loop;
end;

anonymous block completed
分配的空間:4
/US/DE/GB/NL

/**聯合數組存在這比較多的不同:
 **1、聲明方式不一樣;
 **2、不用顯式分配空間
 **3、刪除之後,空間被回收,但是序號依然存在,爲此輸出值的時候需要注意這些不存在值的序號,否則會報錯
 **/
set serveroutput on;
declare
no int :=1;
type variable_array is table of char(2) index by binary_integer;--沒有空間分配的限定設置
vtable variable_array ;---聲明的方式有所不同;
begin
for i in (select distinct COUNTRY_ISO_CODE from countries where rownum<6)loop
----vtable.extend;            --分配空間     
    vtable(no):=i.COUNTRY_ISO_CODE;
    no := no+1;
end loop;
dbms_output.put_line('分配的空間:'|| vtable.count);---可以看到結果爲5
vtable.delete(2);
dbms_output.put_line('刪除後分配的空間:'|| vtable.count);---可以看到結果爲4,即已經回收了刪除的空間
if  vtable.exists(2)=false then         
dbms_output.put_line('刪除之後的元素不再存在');----可以看到該元素已經不存在
end if;
for i in 3..vtable.count loop   ---如果這裏包含不存在的元素2的話,會報錯。
    dbms_output.put('/'||vtable(i));
    if i=vtable.count then
    dbms_output.new_line;
    end if;
end loop;
end;

3、記錄

     record,保存的是一行數據。與%TYPE,%ROWTYPE用起來比較方便。可以隨着表列類型的更新而更新。

/**record只是保存返回的一行記錄;
 **不過,record比較方便的就是其類型可以隨着表列類型的更新而更新;
 **/
set serveroutput on;
declare
OneRow countries%rowtype;---該record類型對應的是表的所有列;
type Rrecord is record(  ---定義record類型,只是某些表的某些列;
code countries.COUNTRY_ISO_CODE%type,
name countries.COUNTRY_NAME%type
);               
country Rrecord;---聲明對象;
begin
select * into OneRow from countries where rownum<2;----注意,只能往其中輸入一行數據,否則會報錯:ORA-01422: 實際返回的行數超出請求的行數;

select country_iso_code,country_name into country from countries where rownum<2;--部分列

dbms_output.put_line('國家ID:'||country.code);
dbms_output.put_line('國家名稱:'||country.name);
end;

anonymous block completed
國家ID:US
國家名稱:United States of America

4、保存列表數據

      上面提到的都是保存一維數組,如果需要保存多維數組的話,可以利用嵌套來實現。

record+varray/嵌套表/聯合數組。三種集合類型用法比較相似,爲此只是對varray舉例

declare
no int :=1;
type Rrecord is record(
code countries.COUNTRY_ISO_CODE%type, 
name countries.COUNTRY_NAME%type);----定義record記錄類型
type var is varray(3) of Rrecord;-----定義記錄集合數組
multirow var := var();----------------聲明記錄集合數組
begin
multirow.extend(3);---分配空間;
select country_iso_code,country_name BULK COLLECT INTO multirow from countries where rownum<4;---批量插入數據;
----輸出結果
for i in 1..multirow.count loop
    dbms_output.put_line(i||'   code:'||multirow(i).code||'     name:   '||multirow(i).name);
end loop;
end;

anonymous block completed
1   code:US     name:   United States of America
2   code:DE     name:   Germany
3   code:GB     name:   United Kingdom

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