oracle集合


oracle集合

1初識集合

集合是oracle中的一種數據類型 存放一組數據類型相同的數據

集合組成

下標組成
下標的類型包含數字(整數,pls_integer,binary_integer)和字符串
值的類型可以是數據庫中的所有類型(基本數據類型,記錄類型(record,%rowtype),%type,集合類型)

集合三種類型

集合是一個比較廣義的概念,在pl/sql中提供了3中類型的集合

索引表

  • 可以通過數字或字符串作為下標來查找其中的元素,僅在pl/sql中使用

嵌套表

  • 擁有索引表的所有特性,但是下標只能是數字類型(連續的整數)
  • 可以在plsql中使用也可以在數據庫中使用

變長數組

  • 下標只能是數字類型,創建時需要指定最大長度
  • 可以在plsql中使用也可以在數據庫中使用

2索引表類型

2.1語法

定義一個索引表類型
type 類型名稱 is table of 元素值的數據類型 index by 下標的數據類型;

索引變量的聲明
變量名 類型名;

索引變量的使用
變量名(下標);

2.2簡單使用

declare 
  --定義一個索引表類型
  type itype is table of varchar2(30) index by pls_integer;
  --聲明一個集合變量
  ind itype;
begin
  ind(1):='張三';
  ind(4):='李四';
  dbms_output.put_line(ind(4)||','||ind(1));
end;

輸出

李四,張三

3集合的屬性或方法

3.1屬性或方法簡單匯總

集合屬性/方法 描述
first 取集合第一個元素的下標
last 取集合元素最后一個元素的下標
next(下標) 取集合當前下標的下一個元素的下標
prior(下標) 取集合當前下標的上一個元素的下標
count 取集合中元素的個數
delete 刪除集合中的元素
limit 取集合最大的元素的個數(變長數組)

3.2屬性或方法示例

declare
  --定義一個集合類型
  type itype is table of varchar2(30) index by varchar2(30);
  --聲明一個索引表
  eng itype;
begin
  --給索引表賦值
  eng('a'):='張三';
  eng('b'):='李四';
  eng('c'):='王五';
  eng('d'):='趙六';
  --打印集合中第一個元素的下標
  dbms_output.put_line('第一個元素的下標: '||eng.first);
  --打印集合中最后一個一個元素的下標
  dbms_output.put_line('最后一個元素的下標: '||eng.last);
  --打印集合中第二個元素的下標
  dbms_output.put_line('第二個元素的下標: '||eng.next(eng.first));
  --打印集合中倒數第二個元素的下標
  dbms_output.put_line('倒數第二個元素的下標: '||eng.prior(eng.last));
  --打印集合中元素的個數
  dbms_output.put_line('元素個數: '||eng.count);
end;

輸出

第一個元素的下標: a
最后一個元素的下標: d
第二個元素的下標: b
倒數第二個元素的下標: c
元素個數: 4

declare
  --定義一個集合類型
  type itype is table of varchar2(30) index by varchar2(10);
  --定義一個變量保存集合的下標
  v_ind varchar(10);
  --聲明一個索引表
  eng itype;
begin
  --給索引賦值
  eng('a'):='張三';
  eng('b'):='李四';
  eng('c'):='王五';
  eng('d'):='趙六';
  
  --遍歷打印集合中的元素
  --將第一個元素的下標放入變量v_ind中
  v_ind:=eng.first;
  loop
    --打印集合元素
    dbms_output.put_line(eng(v_ind));
    --判斷退出條件,當下標的值等於最后一個下標的值
    exit when v_ind=eng.last;
    --循環控制語句
    v_ind:=eng.next(v_ind);
  end loop;
end;

輸出:

張三
李四
王五
趙六

4bulk collect語句循環遍歷

集合提供了bulk collect語句獲取表中數據
通過bulk colleck語句存入集合中的元素下標從1開始並且是連續的

注意:集合下標必須數字類型

4.1語法1

select 列.. bulk collect into 集合變量 from 表 where條件

獲取emp表中30部門中的員工號和姓名

declare
  --定義索引表集合存儲emp表中empno和ename
  type i_empno is table of emp.empno%type index by pls_integer;
  type i_ename is table of emp.ename%type index by pls_integer;
  --定義索引變量
  eno i_empno;
  eme i_ename;
begin
  --bull collect語句獲取empno和ename
  select empno,ename bulk collect into eno,eme from emp where deptno=30;
  for i in eno.first..eno.last loop
    dbms_output.put_line(eno(i)||eme(i));
  end loop;
end;

輸出

7499ALLEN
7521WARD
7654MARTIN
7698BLAKE
7844TURNER
7900JAMES

4.2語法2

execute immediate 'select語句' bulk collect into 集合變量

獲取emp表中30部門中的員工號和姓名

declare
  --聲明一個變量存放selqct查詢結果
  v_sql varchar2(255);
  --定義索引表集合存儲emp表中empno和ename
  type i_empno is table of emp.empno%type index by pls_integer;
  type i_ename is table of emp.ename%type index by pls_integer;
  --定義索引變量
  eno i_empno;
  eme i_ename;
begin
  --將sql語句賦值給v_sql
  v_sql:='select empno,ename from emp where deptno=30';
  --bulk collect語句,將v_sql查詢到的結果放到eno和eme中
  execute immediate v_sql bulk collect into eno,eme;
  --循環打印eno和eme中所有的數據
  for i in eno.first..eme.last loop
    dbms_output.put_line(eno(i)||eme(i));
  end loop;
end;

輸出

7499ALLEN
7521WARD
7654MARTIN
7698BLAKE
7844TURNER
7900JAMES

4.3語法3

fetch 游標 bulk collect into 集合變量

獲取emp表中30部門中的員工號和姓名

declare
  --聲明一個游標
  cursor cur is select empno,ename from emp where deptno=30;
  --聲明集合,存放empno和ename
  type i_empno is table of emp.empno%type index by pls_integer;
  type i_ename is table of emp.ename%type index by pls_integer;
  --聲明索引變量
  eno i_empno;
  eme i_ename;
begin
  --打開游標
  open cur;
  --bulk collect語句,將cur查詢到的結果放到eno和eme中
  fetch cur bulk collect into eno,eme;
  --關閉游標
  close cur;
  
  --循環打印出eno和eme集合中的所有數據
  for i in eno.first..eno.last loop
    dbms_output.put_line(eno(i)||','||eme(i));
  end loop;
end;

輸出

7499,ALLEN
7521,WARD
7654,MARTIN
7698,BLAKE
7844,TURNER
7900,JAMES

5嵌套表

嵌套表和索引表一樣都是存放一組數據類型相同的數據
它的下標只能是整數類型(下標是連續的整數)

嵌套表即可以在plsq中使用,也可以在數據庫中使用
在使用前需要初始化嵌套表變量

5.1plsql中使用

語法

定義嵌套表類型

type 類型名 is table of 存儲的數據的數據類型(長度);

嵌套表變量聲明

變量名 嵌套表類型名;

使用
1初始化嵌套表

  --初始化一個空的嵌套表
  變量名:=嵌套表類型名();
  --初始化一個帶元素的嵌套表
  變量名:=嵌套表類型名(值,值,值,..,值);

2擴展嵌套表

變量名.extend(n);

3賦值

變量名(下標):=值;

初始化一個空的嵌套表

declare
  --聲明一個嵌套表類型
  type mytype is table of varchar2(20);
  --聲明一個變量
  c1 mytype;
begin
  --初始化c1
  c1:=mytype();
  --打印嵌套表的元素個數
  dbms_output.put_line(c1.count);
  --將嵌套表c2擴展2個元素
  c1.extend(1);
  --打印嵌套表的個數;
  dbms_output.put_line(c1.count);
  --擴展幾個元素才能添加幾個
  c1(1):='A';
  c1.extend(5);
  for i in 2..6 loop
    c1(i):=chr(64+i);
  end loop;
  --遍歷嵌套表
  for i in c1.first..c1.last loop
    dbms_output.put_line(c1(i));
  end loop;
end;  

輸出

0
1
A
B
C
D
E
F

初始化一個帶元素的嵌套表

declare
  --定義一個嵌套表
  type mytype is table of varchar(20);
  --聲明一個變量
  c2 mytype;
begin
  --初始化嵌套表c1
  c2:=mytype('SMTIH','ALIEN','SCOTT','TOM');
  --打印嵌套表c2的個數
  dbms_output.put_line(c2.count);
  --擴展2個元素
  c2.extend(2);
  --打印嵌套表c2的個數
  dbms_output.put_line(c2.count);
  --再次添加一個元素
  c2(6):='張三';
  --遍歷嵌套表
  for i in c2.first..c2.last loop
    dbms_output.put_line(c2(i));
  end loop;
end;

輸出

4
6
SMTIH
ALIEN
SCOTT
TOM

張三

5.2數據庫中使用

如果在pl/sql中使用嵌套表,那么其功能與索引表比較相似
嵌套表的一個重要的特色是支持作為數據表列 存儲
因此可以將嵌套表存儲在數據表中或者從數據表中取出嵌套表
這是索引表不具有的功能

為了讓嵌套表類型能在數據表中使用,要求嵌套表類型必須保存到數據字典中
因此需要使用create type語句創建一個持久的嵌套表類型

創建語法

create type 類型名 is table of 元素數據類型;
create type ctype is table of varchar2(30);
declare
  --聲明一個嵌套表類型變量
  c ctype;
begin
  select ename bulk collect into c from emp where deptno=10;
  for i in c.first..c.last loop
    dbms_output.put_line(c(i));
  end loop;
end;

輸出

june
CLARK
KING
MILLER

5.3嵌套表類型在建表時使用

語法

create table 表名(
  列名 類型,
  嵌套表列名 嵌套表類型
)nested table 嵌套表列名 store as 表名

建表

create table x(
  id number(10),
  namelist ctype
)nested table namelist store as y;

查看表x和表y的結構

SQL> desc x;
Name     Type       Nullable Default Comments 
-------- ---------- -------- ------- -------- 
ID       NUMBER(10) Y                         
NAMELIST CTYPE      Y                         
SQL> desc y;
Name Type Nullable Default Comments 
---- ---- -------- ------- -------- 

插入數據

insert into x(id,namelist) values(10,ctype('SMITH','SCOTT','ALIEN'));

查看數據

SQL> select * from x;
         ID NAMELIST
----------- --------
         10 <Object>

這里需要使用 table的子查詢
用來專門查詢復雜類型,
單行單列的子查詢,而且子查詢的列必須是集合列

SQL> select * from table(select namelist from x where id=10);
COLUMN_VALUE
------------------------------
SMITH
SCOTT
ALIEN

6變長數組

下標同樣只能是數字類型,使用前需要初始化,和擴展
變長數組類型在定義時,需要指定它的最大長度
變長數組在擴展時,不能超過最大長度

6.1在plsql代碼塊中使用

語法

創建語句

type 類型名 is varray(最大長度) of 元素的數據類型;

使用
1初始化

  變量名:=類型名(); --初始化一個空的變長數組
  變量名:=類型名(元素值,元素值,..);--初始化一個帶元素的變長數組

2擴展

變量名.extend(n)

3賦值

變量名(n):=值

注意 : 使用在bulk collect into語句中時,不需要初始化和擴展

declare
  --定義一個類型
  type atype is varray(5) of varchar2(30);
  --聲明一個變量
  a atype;
begin
  --初始化
  a:=atype();
  dbms_output.put_line(a.limit);
  --擴展
  a.extend(4);
  for i in 1..4 loop
    a(i):=chr(96+i);
  end loop;
  for i in a.first..a.last loop
    dbms_output.put_line(a(i));
  end loop;
end;

輸出

5
a
b
c
d

注意 : 變長數組擴展時,不能超過最大長度

6.2在數據庫中使用

創建語法

create type 類型名 is varray(長度) of 類型;

查詢emp表中工資排名第5位到第14位的姓名

create type atype is varray(10) of varchar2(30);
declare
  --聲明一個變長表類型變量
  a atype;
begin
  select ename bulk collect into a from 
  (select ename,row_number() over(order by sal desc 
  nulls last) ranks from emp) where ranks between 5 and 14;
  for i in a.first..a.last loop
    dbms_output.put_line(a(i));
  end loop;
end;

6.3在建表時使用

語法

create table 表名(
  變量 類型,
  變長數組列 變長數組類型
);
SQL> create table z(
  2    id number(10),
  3    namelist atype
  4  );
Table created
SQL> insert into z(id,namelist) values(10,atype('Aa','Bb','Cc','Dd'));
1 row inserted

SQL> commit;
Commit complete
SQL> select * from z;
         ID NAMELIST
----------- --------
         10 <Object>
SQL> select * from table(select namelist from z where id=10);
COLUMN_VALUE
------------------------------
Aa
Bb
Cc
Dd


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM