--==================collection======================
--是按某種順序排列的一組元素,所有的元素有相同的數據類型,每個元素有唯一一個下標標識在這一組元素中的位置.
--集合的出現是爲了遵循面向對象的編程風格,而且 ,相對於兩個表,存儲在集合中的數據可以被數據庫更快的訪問
--Collection主要有3類:
-------關聯數組:鍵值對的集合,其中鍵是唯一的,用於確定數組中對應的值,類似java中的hash表,
-----------------鍵可以是整數或字符串.第一次使用鍵來指派一個對應的值就是添加元素,而後續這樣的操作就是更新元素.
-------嵌套表(後續補齊)
-------Varry數組,變長數組(後續補齊)
--============首先看看關聯數組的使用================
----TYPE 關聯數組的名字 is table of 關聯數組的存儲元素類型[not null]
---- index by [binary_integer][pls_integer][varhcar2(size)];
declare
--聲明類型
type t_indtab is table of number index by binary_integer;
v_indtab t_indtab ;--聲明變量
v2 v_indtab%type; -- v2和v1 同類型
begin
v_indtab(1) :=1;
v_indtab(5) :=3;
v2(6) :=6;
v2(6) :=10;
dbms_output.put_line(v_indtab(5));-- 3
dbms_output.put_line(v_indtab(6)); -- 10
end;
----關聯數組的方法:
-------exists(n) :判斷第n個元素是否存在.
-------count();返回聯合數組的元素個數,不包括被刪除的元素.對於空的聯合數組,返回值也是0
------- 在使用count()方法前,建議你先用exists來判斷一下.這樣可以避免拋出異常.
-------first/last:返回最小和最大下標號,如果collection爲空,則返回null;
-------prior(n)/next(n):返回第n個元素的前一個元素的下標和後一個元素的下標.如果不存在,則返回null;
-------trim(n): 從最後一個元素刪除n個元素.不能用於關聯數組
-------delete:刪除所有元素
-------delete(n):刪除第n個元素
-------delete(m,n):從第m個元素刪除到第n個元素.
------- 關聯數組的遍歷(for循環)
declare
type t_ind_tab is table of number index by binary_integer;--聲明類型
v_indtab t_ind_tab; --定義變量
begin
--賦值
v_indtab(1) :=1;
v_indtab(5) :=3;
v_indtab(6) :=4;
for i in v_indtab.first .. v_indtab.last LOOP
if v_indtab. exists(i)
then dbms_output.put_line(v_indtab(i));
end if ;
end loop;
end;
------- 關聯數組的遍歷(while循環)
declare
type ind_tab is table of varchar2(5) index by varchar2(4);
v_indtab ind_tab;
v_index varchar2;
begin
--賦值
v_indtab('a') :='1';
v_indtab('b') :='3';
v_indtab('c') :='4';
v_index := v_indtab.first;
while v_index <= v_indtab.last LOOP -- 如果當前的索引下標 <= 最後一個下標
dbms_output.put_line(v_indtab(v_index));
v_index :=v_indtab.next(v_index); --通過next函數獲取當前索引的下一個下標
end loop;
end;
--==========批量綁定==========================
--採用bulk collect可以將查詢結果一次性地加載到collections中,
--而不是通過cursor一條一條的處理, 通過bulkcollect減少loop處理的開銷.
--可以在select into ,fetch into ,returning into語句使用bulkcollect.
--注意在使用bulk collect時,所有的into變量都必須是collections.
-- 打印每個emp的ID,ENAME;
declare
--聲明record類型
type t_emp_rec is record(
id emp.deptno%type,
name emp.ename%type
);
--聲明關聯數組的類型, 存儲是元素師 record類型
type emp_indtab is
table of t_emp_rec index by binary_integer;
v_emp emp_indtab; --定義關聯數組的變量
begin
--BULK COLLECT則一次即可提取所有行並綁定到記錄變量。即謂批量綁定
select deptno , ename bulk Collect into v_emp -- into的變量:必須是集合.
from emp where 1 = 1 ;
for i in v_emp.FIRST .. v_emp.LAST LOOP --用for操作集合
-- v_emp是關聯數組.訪問其中的某一個元素 v_emp(i); ,不能用v_emp[i];
dbms_output.put_line(v_emp(i).id || ':'|| v_emp(i).NAME);
end loop;
end;
-- 如果數據量較大,可以採用Limit來限制fetch的數量
-- 重複上述問題:打印每個emp的ID,ENAME;(每次取出5條記錄到bulk collect;
declare
cursor emp_cur is --遊標變量 查詢所有的記錄
select deptno , ename from emp ;
type emp_rec is record ( --聲明類型
id emp.deptno%type,
name emp.ename%type
);
type emp_indtab is table of
emp_rec index by binary_integer;
v_emp emp_indtab; --定義關聯數組的變量,沒有初始化
v_limit PLS_INTEGER := 5; --定義了一個變量來作爲limit的值
begin
open emp_cur; --執行sql
LOOP
fetch emp_cur bulk collect into v_emp limit v_limit;
exit when v_emp.count = 0;--此時遊標退出使用了v_emp.COUNT
for i in v_emp.FIRST .. v_emp.LAST LOOP
dbms_output.put_line(v_emp(i).id || ':'|| v_emp(i).NAME);
end loop;
dbms_output.put_line('---------------------');
end loop;
close emp_cur;--關閉
end;