更新時間:2021-03-11 17:49:13 來源:動力節點 瀏覽1732次
顧名思義,關聯數組(以前被稱為PL/SQL表或索引表)是一個鍵值對的集合,每個鍵是一個唯一性索引,用于定位與之關聯的值。在Oracle數據庫中,關聯數組同樣扮演著舉足輕重的角色。Oracle關聯數組的語法格式是:
變量名(索引)
索引的數據類型可以是字符類型(VARCHAR2, VARCHAR, STRING或LONG),也可以是PLS_INTEGER。索引以排序的狀態被存儲,而不是以被創建時的順序,對于字符類型的索引,排序順序取決于初始化參數NLS_SORT和NLS_COMP,像數據庫表一樣,關聯數組可以:
是空的(但不是NULL)直到你填充它;
可以存放不指定數量的元素,你可以不需要直到它們的位置而訪問到它們;
不像數據庫表的方面:
不需要磁盤空間或網絡操作;
不能被DML語句操作;
樣例程序 - 使用字符串作為索引的關聯數組
DECLARE
????TYPE population IS TABLE OF NUMBER ??-- 關聯數組的類型
????????INDEX BY VARCHAR2(64); ??????????-- 索引的類型是字符串
????city_population population; ?????????-- 關聯數組變量
????i ?VARCHAR2(64); ????????????????????-- 標量變量
BEGIN
????-- 向關聯數組中添加鍵值對
????city_population('Smallville') ?:= 2000;
????city_population('Midland') ????:= 750000;
????city_population('Megalopolis') := 1000000;
????-- 改變與鍵'Smallville'關聯的值
????city_population('Smallville') := 2001;
????-- 打印關聯數組
????i := city_population.FIRST; ???-- 獲得關聯數組的第一個元素
????WHILE i IS NOT NULL
????LOOP
????????DBMS_OUTPUT.PUT_LINE(
????????????'Population of ' || i || ' is ' || city_population(i)
????????);
????????i := city_population.Next(i); ???-- 獲得關聯數組的下一個元素
????END LOOP;
END;
/
樣例程序 - 返回使用PLS_INTEGER作為索引的關聯數組
DECLARE
????TYPE sum_mutiples IS TABLE OF PL_INTEGER
????????INDDEX BY PLS_INTEGER;
????n ?PLS_INTEGER := 5;
????sn PLS_INTEGER := 10;
????m ?PLS_INTEGER := 3;
????FUNCTION get_sum_multiples (
????????multiple IN PLS_INTEGER,
????????num ?????IN PLS_INTEGER
????) RETURN sum_mutiples
????IS
????????s sum_mutiples;
????BEGIN
????????FOR i IN 1..num
????????LOOP
????????????s(i) := multiple * ((i* (i + 1)) / 2)
????????END LOOP;
????????RETURN s;
????END get_sum_multiples;
BEGIN
????DBMS_OUTPUT.PUT_LINE(
????????'Sum of the first ' || TO_CHAR(n) || ' multiples of ' ||
????????TO_CHAR(m) || ' is ' || TO_CHAR(get_sum_multiples(m, sn)(n))
????);
END;
/
1、聲明關聯數組常量
要想聲明一個關聯數組常量,你必須創建一個函數,用來使用初始值填充這個關聯數組,并在常量聲明的時候調用這個函數。
樣例程序如下:
CREATE OR REPLACE PACKAGE My_Types AUTHID CURRENT_USER
IS
????TYPE My_AA IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER;
????FUNCTION Init_My_AA RETURN My_AA;
END My_Types;
/
CREATE OR REPLACE PACKAGE BODY My_Types
IS
????FUNCTION Init_My_AA RETURN My_AA
????IS
????????Ret My_AA;
????BEGIN
????????Ret(-10) := '-ten';
????????Ret(0) := 'zero';
????????Ret(1) := 'one';
????????Ret(2) := 'two';
????????Ret(3) := 'three';
????????Ret(4) := 'four';
????????Ret(9) := 'nine';
????????RETURN Ret;
????END Init_My_AA;
END My_Types;
/
DECLARE
????v CONSTANT My_Types.My_AA := My_Types.Init_My_AA();
BEGIN
????DELARE
????????Idx PLS_INTEGER := v.FIRST();
????BEGIN
????????WHILE Idx IS NOT NULL
????????LOOP
????????????DBMS_OUTPUT.PUT_LINE(
????????????????TO_CHAR(Idx, '999') || LPAD(v(Idx), 7)
????????????);
????????????Idx := v.NEXT(Idx);
????????END LOOP;
????END;
END;
/
2、NLS參數值對以字符串作為索引的關聯數組的影響
NLS參數(例如NLS_SORT, NLS_COMP和NLS_DATE_FORMAT)會對以字符串作為索引的關聯數組產生影響,在填充關聯數組后改變NLS參數值,初始化參數NLS_SORT和NLS_COMP會決定關聯數組的字符串索引的存儲順序。
如果你在填充關聯數組后改動了這些參數值,那么在你調用集合方法FIRST, LAST, NEXT和PRIOR時可能會得到非預期值或拋出異常,如果要避免這種情況,可以在你操作關聯數組的會話里改回這些參數的原來值。不是VARCHAR2的索引數據類型
以字符串作為索引的關聯數組,在聲明時字符串類型必須是VARCHAR2或其子類型。然后,你在填充關聯數組時,可以使用其他數據類型作為索引,只要能使用TO_CHAR函數,將其轉換為VARCHAR2類型。如果你聲明的關聯數組的索引數據類型不是VARCHAR2及其子類型,那么一定要確保這些索引在初始化參數改變時能保持一致并唯一,例如:
不要使用TO_CHAR(SYSDATE)作為索引,因為如果NLS_DATE_FORMAT參數值改變,那么TO_CHAR(SYSDATE)的值可能會改變;
不要使用NVARCHAR2類型,因為有些不同的NVARCHAR2索引可能會轉換成同一個VARCHAR2值;
不要使用只在大小寫或重音位置上不同的CHAR或VARCHAR2類型索引,因為當NLS_SORT或 _CI 或 _AI結尾的參數值改變,這些索引可能會轉換成同一個值傳遞關聯數組至遠程數據庫;
如果你將關聯數組作為參數傳遞給遠程數據庫,那么本地數據庫和遠程數據庫在NLS_SORT或NLS_COMP參數上有不同的設置值,就會:集合方法FIRST, LAST, NEXT和PRIOR可能會得到非預期值或拋出異常。在本地數據庫保持唯一的索引,可能在遠程數據庫中不再保持唯一性,導致拋出VALUE_ERROR異常
3、關聯數組的適當使用
關聯數組適用于:
用作小型的關聯的lookup表,當你調用子程序或初始化包時在內存中構建它在本地和遠程數據庫服務器間傳遞關聯數組通常用于保存臨時數據,為了使它與數據庫會話有相同的生命周期,可以在包頭中聲明它,在包體中填充它。
Oracle關聯數組的應用遠不止于此,本文我們只是了解了一些最基本的使用方法。實際上,Oracle數據庫中關聯數組的使用往往是錯綜復雜的,需要結合索引,具體情況下具體分析。在本站的Oracle教程中,對一些常用的情況給出了分析,想了解的小伙伴可以自己前去學習。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習