天天看點

Oracle的數組

提叻一個代碼段,要人幫助解釋一下。 

代碼段如下: 

複制代碼代碼如下:

declare 

type t_indexby is table of number 

index by binary_integer; 

type t_nesteed is table of number; 

type t_varray is varray(10) of number; 

v_indexby t_indexby; 

v_nested t_nested; 

v_varray t_varray; 

begin 

v_indexby(1):=1; 

v_indexby(2):=2; 

v_nested:=t_nested(1,2,3,4,5); 

v_varray:=t_varray(1,2); 

end; 

一段很簡單的有關Oracle裡數組的sample代碼。看着這段由代表性的代碼,不由想起自己以前獨自摸索Oracle裡數組類型的那種不弄明白決不姑息的激情。 

這段代碼也還不錯,通過簡單的執行個體就把主要的數組類型都羅列出來叻,好的素材 不由又激發其我回答寫寫的欲望叻,是以也不吝指力,總結叻一番,也順便填補一下我以前忘記歸納總結的空缺 

這段代碼,收羅叻Oracle裡數組的使用方式 

1. index by table 

2. nested table 

3. varray 可變數組 

這裡是Oracle文檔裡對這三種數組類型的介紹 

An index-by table is the most flexible and generally best-performing collection type for use inside PL/SQL programs. 

A nested table is appropriate for large collections that an application stores and retrieves in portions. 

A VARRAY is appropriate for small collections that the application stores and retrieves in their entirety. 

這裡是對通過應用性上的對他們三者的概括,好像沒有給我們太直接的影響,還是讓我們先對其了解,這裡的應用性上展現的東西也就好了解叻。 

sample code中以對三種不同的type定義的方式開始。 

type t_indexby is table of number index by binary_integer; -- indexed by table 

type t_nesteed is table of number; -- nested table 

type t_varray is varray(10) of number; -- varray 

上兩句和後一句有明顯的不同,沒有定義長度,而varray定義叻長度。varray有長度限制,通路是超過長度的話将提示越界的錯誤。而indexed by table和nested table顯然沒有這個限制,不過對于indexed by table和nested table,他們兩個也是有差別的。 

上面sample的後部分就描述了兩者的差別,對于index by table來說,這裡已經指定了index的類型,直接用index的類型的變量做索引來辨別着每個元素,而不需要擴充大小。這個功能有些像java裡的map(有差別就是這裡key是有順序的),而nested table能則完全和list一樣 

我們通過sample來看看 

這裡分别在v_indexby裡加了兩個元素,為1, 1和2,2,注意這裡的(1),(2)和後面nested table已經varray裡的不一樣, 

這裡,我把它了解為key,而不是元素的序号。是以index by這裡的下标,不一定是連續的,可以跳躍,而另兩者就不同,另外兩個是名符其實的數組對象了,下标表示的就是元素的序号,和java不同,從1開始。 

這裡分别是定義了5個和2個元素的數組。 

v_nested:=t_nested(1,2,3,4,5); 5個元素,值為1,2,3,4,5 

v_varray:=t_varray(1,2); 2個元素 值為1,2 

強調一下,對于nested table來說,需要使用extend來擴充數組,添加元素的時候,而varrray不需要(已經知道長度了,定義的時候)。 

v_nested.extend; v_nested(v_nested.count) := 6; 

大家在這裡基本上已經可以看到他們的差別了,index by table在結構上和nested table以及Varray有着本質的不同,那麼勢必使用的時候肯定不同了。由于index by table下标并不是序号,是以我們隻能通過key來通路了,這裡和java倒是一樣的。 

上面的例子裡,沒有提供,而且我在網上找了很多的介紹都沒有詳細給出過index by table的周遊的方法的,這裡我自己寫了一個sample,供大家學習參考 

type t_array is table of varchar2(1000) index by binary_integer; 

v_array t_array; 

v_idx number; 

v_array(1) := 'a1'; 

v_array(2) := 'a2'; 

v_array(-1) := 'a-1'; -- 是key是以可以為負數 

v_idx := v_array.first; 

loop 

exit when v_idx is null; 

dbms_output.put_line(v_array(v_idx)); 

v_idx := v_array.next(v_idx); 

end loop; 

結果 

a-1 

a1 

a2 

注意這裡的方法,first,傳回第一個key,next()傳回下一個key 

對于nested table來說,下标是序号,是不能為負數的 

type t_array is table of varchar2(1000); 

v_idx varchar2(1000); 

v_array := t_array(); --- 一定要先初始話。 

v_array.extend; ---- 擴充數組 

v_array.extend; 

v_array(3) := 'a-1'; ---- v_array(-1) := 'a-1'; 将出錯 

dbms_output.put(v_idx||' '); 

看看nested tabled的通路也可以和上面一樣,當然也可以用更簡單的方法來周遊 

for i in 1..v_array.count loop 

dbms_output.put(i||' '); 

dbms_output.put_line(v_array(i)); 

其實可以看到和java裡的list的通路很類似了。 

這個知識點,很多人都寫過sample,内容不是很多,但是小知識也要積累,勸學裡 “不積跬步,無以至千裡,不積小流,無以成江海”,學習固然如此,而Oracle的學習更應如此。 以前的庸惰,我今天還是還叻。 “走江湖的,遲早要還的”。 

Oracle對Index by 數組的官方介紹