使用集合
象記錄一樣,集合可以在兩個層面上使用:
. 操作整個集合
. 訪問集合中的單個元素
第一種情況使用集合名,第二種情況使用下標:
collection(subscript)
index_by表的下標是兩為的整數,可以為正也可以為負,范圍是:-2147483647--2147483647。嵌套表和VARRAY表示元素在集合中的位置,用戶很難靈活設計下標,這是因為:
. 嵌套表開始是緊密的(相對於疏松)
. VARRAY始終保持緊密
. 這兩種集合的下標都由1開始
初始化、刪除、引用集合
使用集合之前必須要初始化,對於Index_by表初始化是自動進行的,但是對於嵌套表和VARRAY就必須使用內建的構造函數。如果重新調用,嵌套表和VARRAY自動置NULL,這不只是元素置NULL,而是整個集合置NULL。給集合內的元素賦值需要使用下標符號。將一個集合的值賦給另一個集合,只需要簡單的使用賦值操作符。
Index_by集合初始化是最簡單的,只要涉及其中的一個元素集合就被初始化了。
例:
DECLARE
TYPE symbol_tab_typ IS TABLE OF VARCHAR2(5) INDEX BY BINARY_INTEGER;
TYPE account_tab_typ IS TABLE OF account%ROWTYPE INDEX BY BINARY_INTEGER;
symbol_tab symbol_tab_typ;
account_tab account_tab_typ;
new_acct_tab account_tab_typ;
BEGIN
--初始化集合元素147和-3
SELECT * INTO account_tab(147)
FROM accounts WHERE account_nbr=147;
SELECT * INTO account_tab(-3)
FROM accounts WHERE account_nbr=3003;
IF account_tab(147).balance<500 THEN
chang_maintenance_fee(147);
END IF
new_acct_tab:=account_tab;
symbol_tab(1):="ORCL";
symbol_tab(2):="CSCO";
symbol_tab(3):="SUNM";
publish_portfolio(symbol_tab);
嵌套表和VARRAY由構造函數初始化,構造函數和集合的名字相同,同時有一組參數,每個參數對應一個元素,如果參數為NULL,那麼對應的元素就被初始化為NULL,如果創建了元素,但沒有填充數據,那麼元素將保持null值,可以被引用,但不能保持數據。如果元素沒有初始化,那麼就不能引用該元素。
例:
DECLARE
TYPE stock_list IS TABLE OF stock.symbol%TYPE;
TYPE top10_list IS VARRAY (10) OF stocks.symbol%TYPE;
biotech_stocks stock_list;
tech_10 top10_list;
BEGIN
--非法,集合未初始化。
biotech_stocks(1):='AMGN';
IF biotech_stocks IS NULL THEN
--初始化集合
biotech_stocks:=('AMGN','BGEN',IMCL','GERN',CRA');
END IF;
tech_10:=top10_list('ORCL',CSCO','MSFT','INTC','SUNW','IBM',NULL,NULL);
IF tech_10(7) IS NULL THEN
tech_10(7):='CPQ';
END
tech_10(8):='DELL';
在這個例子中,嵌套表BIOTECH_STOCKS初始化有5個元素,VARRAY tech_10集合最多能有10 個元素,但構造函數只創建了8個元素,其中還有兩個元素是NULL值,並程序中給他們賦值。
初始化基於記錄的集合,就必須將記錄傳遞給構造函數,注意不能只是簡單的將記錄的域傳遞給構造函數。
例:
DECLARE
TYPE stock_quote_rec IS RECORD
(symbol stock.symbol%TYPE
,bid NUMBER(10,4)
,ask NUMBER(10,4)
,volume NUMBER NOT NULL:=0
);
TYPE stock_tab_typ IS TABLE OF stock_quote_rec;
quote_list stock_tab_typ;
single_quote stock_quote_rec;
BEGIN
single_quote.symbol:='OPCL';
single_quote.bid:=100;
single_quote.ask:=101;
single_quote.volume:=25000;
--合法
quote_list:=stock_tab_typ(single_quote);
--不合法
quote_list:=stock_tab_typ('CSCO',75,76,3210000);
DBMS_OUTPUT.LINE(quote_list(1).bid);