很長一段時間內,PL/SQL開發人員必須有一個“index-by表”才能創建某個指定數據類型的或者PL/SQL記錄的表。
因為他們只接受整型數據以從數組中提取數據,所以類型聲明的末尾子句以“INDEX BY BINARY_INTEGER”結束。
如果想以非整型值作為索引,要么你必須創建一個存儲過程來掃描需要的值,要么你必須在一個單獨的表上建立一個索引。
declare
type valrec is record(key varchar2(50),val varchar2(50));
type valtbl is table of valrec index by binary_integer;
mytbl valtbl;
begin
mytbl(1).key := 'foo';
mytbl(1).val := 'bar';
for i in 1..mytbl.count loop
if mytbl(i).key = 'foo' then
dbms_output.put_line(mytbl(i).val);
end if;
end loop;
end;
PL/SQL允許使用index-by表創建某個指定數據類型或者PL/SQL記錄的表。
然而,如果想以非整型值作為索引,要么你必須創建一個存儲過程掃描你需要的值,要么你必須在一個單獨的表上建立一個索引。
Oracle9i擴展了index-by表的語法,允許字符串類型的索引,叫做關聯數組。
有了字符串類型,你現在就可以快速訪問元素,而不用再在每個元素間循環或者去知道它在數組中的位置:
declare
type valtbl is table of varchar2(50) index by varchar2(50);
mytbl valtbl;
begin
mytbl('zhao1') := 'apple';
mytbl('zhao2'):= 'orange';
dbms_output.put_line(mytbl('zhao1'));
dbms_output.put_line(mytbl('zhao2'));
end;
使用字符串索引的關聯數組的一個有趣的特性是它們自動地通過當前的國際語言支持(NLS)設置排序。
FIRST和LAST函數返回數組中以字典序排列的第一個和最后一個健值。NEXT和PRIOR允許你以字典序獲取下一個和前一個鍵。
declare
type valtbl is table of varchar2(50) index by varchar2(50);
mytbl valtbl;
key varchar2(50);
begin
mytbl('b') := 'two';
mytbl('a') := 'one';
mytbl('c') := 'three';
key := mytbl.first;
while key is not null loop
dbms_output.put_line(mytbl(key));
key := mytbl.next(key);
end loop;
end;
因為Oracle可以自動地將任何的數據類型轉換為字符串類型,所以能以字符串作為索引意味著可以以任何數據類型作為索引。
你可以使用這個方法把日期、浮點值、行二進制值和對象引用作為索引。
declare
type timetbl is table of integer index by varchar2(8);
mytbl timetbl;
key varchar2(50);
begin
for row in (select * from emp) loop
key := to_char(row.hiredate,'YYYYMMDD');
if not mytbl.exists(key) then
mytbl(key) := 0;
end if;
mytbl(key) := mytbl(key) + 1;
end loop;
dbms_output.put_line('hiring barchart:');
dbms_output.put_line('----------------');
key := mytbl.first;
while key is not null loop
dbms_output.put_line(
to_char(to_date(key,'YYYYMMDD'),'DD MON, YYYY')
||': '||rpad('#',mytbl(key),'#'));
key := mytbl.next(key);
end loop;
end;
鍵值必須是唯一的并且是大小寫敏感的。在運行時改變NLS值可能會產生運行時錯誤。
對于關聯數組的每一個操作NLS設置必須保持相同。
關聯數組必須在PL/SQL代碼中手工建立。
其它的程序開發語言和接口不能把主機數組綁定到并聯數組,所以你就不能用字符串索引的關聯數組使用BULK COLLECT。