更新時間:2021-03-11 17:49:13 來源:動力節(jié)點(diǎn) 瀏覽2014次
顧名思義,關(guān)聯(lián)數(shù)組(以前被稱為PL/SQL表或索引表)是一個鍵值對的集合,每個鍵是一個唯一性索引,用于定位與之關(guān)聯(lián)的值。在Oracle數(shù)據(jù)庫中,關(guān)聯(lián)數(shù)組同樣扮演著舉足輕重的角色。Oracle關(guān)聯(lián)數(shù)組的語法格式是:
變量名(索引)
索引的數(shù)據(jù)類型可以是字符類型(VARCHAR2, VARCHAR, STRING或LONG),也可以是PLS_INTEGER。索引以排序的狀態(tài)被存儲,而不是以被創(chuàng)建時的順序,對于字符類型的索引,排序順序取決于初始化參數(shù)NLS_SORT和NLS_COMP,像數(shù)據(jù)庫表一樣,關(guān)聯(lián)數(shù)組可以:
是空的(但不是NULL)直到你填充它;
可以存放不指定數(shù)量的元素,你可以不需要直到它們的位置而訪問到它們;
不像數(shù)據(jù)庫表的方面:
不需要磁盤空間或網(wǎng)絡(luò)操作;
不能被DML語句操作;
樣例程序 - 使用字符串作為索引的關(guān)聯(lián)數(shù)組
DECLARE
????TYPE population IS TABLE OF NUMBER ??-- 關(guān)聯(lián)數(shù)組的類型
????????INDEX BY VARCHAR2(64); ??????????-- 索引的類型是字符串
????city_population population; ?????????-- 關(guān)聯(lián)數(shù)組變量
????i ?VARCHAR2(64); ????????????????????-- 標(biāo)量變量
BEGIN
????-- 向關(guān)聯(lián)數(shù)組中添加鍵值對
????city_population('Smallville') ?:= 2000;
????city_population('Midland') ????:= 750000;
????city_population('Megalopolis') := 1000000;
????-- 改變與鍵'Smallville'關(guān)聯(lián)的值
????city_population('Smallville') := 2001;
????-- 打印關(guān)聯(lián)數(shù)組
????i := city_population.FIRST; ???-- 獲得關(guān)聯(lián)數(shù)組的第一個元素
????WHILE i IS NOT NULL
????LOOP
????????DBMS_OUTPUT.PUT_LINE(
????????????'Population of ' || i || ' is ' || city_population(i)
????????);
????????i := city_population.Next(i); ???-- 獲得關(guān)聯(lián)數(shù)組的下一個元素
????END LOOP;
END;
/
樣例程序 - 返回使用PLS_INTEGER作為索引的關(guān)聯(lián)數(shù)組
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、聲明關(guān)聯(lián)數(shù)組常量
要想聲明一個關(guān)聯(lián)數(shù)組常量,你必須創(chuàng)建一個函數(shù),用來使用初始值填充這個關(guān)聯(lián)數(shù)組,并在常量聲明的時候調(diào)用這個函數(shù)。
樣例程序如下:
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參數(shù)值對以字符串作為索引的關(guān)聯(lián)數(shù)組的影響
NLS參數(shù)(例如NLS_SORT, NLS_COMP和NLS_DATE_FORMAT)會對以字符串作為索引的關(guān)聯(lián)數(shù)組產(chǎn)生影響,在填充關(guān)聯(lián)數(shù)組后改變NLS參數(shù)值,初始化參數(shù)NLS_SORT和NLS_COMP會決定關(guān)聯(lián)數(shù)組的字符串索引的存儲順序。
如果你在填充關(guān)聯(lián)數(shù)組后改動了這些參數(shù)值,那么在你調(diào)用集合方法FIRST, LAST, NEXT和PRIOR時可能會得到非預(yù)期值或拋出異常,如果要避免這種情況,可以在你操作關(guān)聯(lián)數(shù)組的會話里改回這些參數(shù)的原來值。不是VARCHAR2的索引數(shù)據(jù)類型
以字符串作為索引的關(guān)聯(lián)數(shù)組,在聲明時字符串類型必須是VARCHAR2或其子類型。然后,你在填充關(guān)聯(lián)數(shù)組時,可以使用其他數(shù)據(jù)類型作為索引,只要能使用TO_CHAR函數(shù),將其轉(zhuǎn)換為VARCHAR2類型。如果你聲明的關(guān)聯(lián)數(shù)組的索引數(shù)據(jù)類型不是VARCHAR2及其子類型,那么一定要確保這些索引在初始化參數(shù)改變時能保持一致并唯一,例如:
不要使用TO_CHAR(SYSDATE)作為索引,因為如果NLS_DATE_FORMAT參數(shù)值改變,那么TO_CHAR(SYSDATE)的值可能會改變;
不要使用NVARCHAR2類型,因為有些不同的NVARCHAR2索引可能會轉(zhuǎn)換成同一個VARCHAR2值;
不要使用只在大小寫或重音位置上不同的CHAR或VARCHAR2類型索引,因為當(dāng)NLS_SORT或 _CI 或 _AI結(jié)尾的參數(shù)值改變,這些索引可能會轉(zhuǎn)換成同一個值傳遞關(guān)聯(lián)數(shù)組至遠(yuǎn)程數(shù)據(jù)庫;
如果你將關(guān)聯(lián)數(shù)組作為參數(shù)傳遞給遠(yuǎn)程數(shù)據(jù)庫,那么本地數(shù)據(jù)庫和遠(yuǎn)程數(shù)據(jù)庫在NLS_SORT或NLS_COMP參數(shù)上有不同的設(shè)置值,就會:集合方法FIRST, LAST, NEXT和PRIOR可能會得到非預(yù)期值或拋出異常。在本地數(shù)據(jù)庫保持唯一的索引,可能在遠(yuǎn)程數(shù)據(jù)庫中不再保持唯一性,導(dǎo)致拋出VALUE_ERROR異常
3、關(guān)聯(lián)數(shù)組的適當(dāng)使用
關(guān)聯(lián)數(shù)組適用于:
用作小型的關(guān)聯(lián)的lookup表,當(dāng)你調(diào)用子程序或初始化包時在內(nèi)存中構(gòu)建它在本地和遠(yuǎn)程數(shù)據(jù)庫服務(wù)器間傳遞關(guān)聯(lián)數(shù)組通常用于保存臨時數(shù)據(jù),為了使它與數(shù)據(jù)庫會話有相同的生命周期,可以在包頭中聲明它,在包體中填充它。
Oracle關(guān)聯(lián)數(shù)組的應(yīng)用遠(yuǎn)不止于此,本文我們只是了解了一些最基本的使用方法。實際上,Oracle數(shù)據(jù)庫中關(guān)聯(lián)數(shù)組的使用往往是錯綜復(fù)雜的,需要結(jié)合索引,具體情況下具體分析。在本站的Oracle教程中,對一些常用的情況給出了分析,想了解的小伙伴可以自己前去學(xué)習(xí)。

初級 202925

初級 203221

初級 202629

初級 203743