2014-12-03 59 views
1

有兩個環節 http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/composites.htm#LNPLS99981嵌套數組和關聯數組有什麼區別?

Purpose of using different types of PL/SQL collections in Oracle

通過上述兩個指向我有兩個疑問

1.Which一個是正確的嵌套表?

2.如果oracle doc是正確的嵌套表和關聯數組之間的區別是什麼?

+0

兩者都不錯。簡而言之,關聯數組有一個'INDEX BY'子句,嵌套表不包含。 – 2014-12-03 10:27:58

+1

如果在oracle文檔中(您提供的第一個鏈接)向上滾動一下,您將看到表5-1,其中突出顯示了不同集合類型之間的差異和相似之處。 – 2014-12-03 11:13:56

+1

另一個重要區別是:您可以在數據庫級別創建嵌套表,並且可以在表中將它們用作列類型。有了關聯數組,你不能這樣做。 – 2014-12-03 12:11:50

回答

3

這是另一個不同之處,它不是那種通常已知的。您可以將兩個嵌套表格與=<>進行比較,但不能關聯數組。

DECLARE 

    TYPE associative_array IS TABLE OF INTEGER INDEX BY PLS_INTEGER; 
    a_var_associative_array associative_array; 
    b_var_associative_array associative_array; 

    TYPE nested_table IS TABLE OF INTEGER; 
    a_var_nested_table nested_table := nested_table(1, 2, 3, 4, 5); 
    b_var_nested_table nested_table := nested_table(5, 4, 3, 2, 1); 

BEGIN 

    IF a_var_nested_table = b_var_nested_table THEN 
     -- Note, the different order of values! 
     DBMS_OUTPUT.PUT_LINE ('TRUE'); 
    ELSE 
     DBMS_OUTPUT.PUT_LINE ('FALSE'); 
    END IF; 

    -- IF a_var_associative_array = b_var_associative_array THEN -> gives you an error! 

END; 

當您使用嵌套表工作,你也可以使用Multiset OperatorsMultiset ConditionsSET這不適用於關聯數組。

+0

感謝您的答案但根據我的知識,如果我們使用關聯數組並將其中的某些值,它存儲的是排序順序,而不是我們輸入的,通過這個我知道嵌套表也排序數據,但爲什麼關聯數組無法比較,因爲它也有一些內存分配在PGA? – 2014-12-03 12:49:04

+0

@Wernfried:謝謝你的信息。我不知道。因此,嵌套表格在進行比較時會被視爲多重表格。有趣。 – 2014-12-03 12:59:28

+0

@PuneetKushwah:我不知道爲什麼甲骨文有這樣的區別。也許是由於關聯數組沒有固定大小的事實。 – 2014-12-03 13:25:41

3

嵌套表只是一個由n個元素組成的數組。

declare 
    type nested_table_of_integer is table of integer; 
    v_my_nested_table nested_table_of_integer; 
begin 
    v_my_nested_table := nested_table_of_integer(); -- initialize 
    v_my_nested_table.extend(10); -- add 10 elements 
    v_my_nested_table(1) := 100; 
    v_my_nested_table(11) := 1000; -- ORA-06533: Subscript beyond count 
end; 

必須如圖所示初始化嵌套表。它首先有零個元素。要添加元素,我們使用EXTEND。這個嵌套表格有10個元素。它們的索引編號爲1到10.元素1的值爲100.其他元素的值爲null。訪問一個不存在的元素,比如說第11個元素,會產生一個錯誤。另一方面,關聯數組是一個名稱/值對數組。讓我們用數字(通常PLS_INTEGER)的命名:

declare 
    type associative_array_of_integer is table of integer index by pls_integer; 
    v_my_associative_array associative_array_of_integer; 
begin 
    v_my_associative_array(1) := 100; 
    v_my_associative_array(11) := 1000; 
    v_my_associative_array(12) := v_my_associative_array(2); -- ORA-01403: no data found 
end; 

關聯數組不需要初始化。它是空的並且被填充。這裏我們將名爲1的元素與值100以及名稱爲11的元素與值1000相關聯。因此,數組中有兩個元素。當我們嘗試訪問不在數組中的名稱時,我們會得到一個沒有數據發現的異常。

我們也可以使用字符串名稱:

declare 
    type associative_array_of_integer is table of integer index by varchar2(100); 
    v_my_associative_array associative_array_of_integer; 
begin 
    v_my_associative_array('age father') := 39; 
    v_my_associative_array('age mother') := 32; 
    v_my_associative_array('age daughter') := 11; 
end; 

你可以用兩個集合來獲得表中的數據,但你不同的方式使用它們。嵌套表有一個數,你可以從1只循環計數來訪問它的元素:

declare 
    type nested_table_of_integer is table of integer; 
    v_my_nested_table nested_table_of_integer; 
begin 
    v_my_nested_table := nested_table_of_integer(); -- initialize 
    select table_name bulk collect into v_my_nested_table from user_tables; 
    for i in 1 .. v_my_nested_table.count loop 
    dbms_output.put_line(v_my_nested_table(i)); 
    end loop; 
end; 

關聯數組但必須從任何恰好是第一個索引到下一個和下一個和下一個使用閱讀FIRST和NEXT。

declare 
    type associative_array_of_integer is table of integer index by pls_integer; 
    v_my_associative_array associative_array_of_integer; 
    i integer; 
begin 
    select table_name bulk collect into v_my_associative_array from user_tables; 
    i := v_my_associative_array.first; 
    while i is not null loop 
    dbms_output.put_line(v_my_associative_array(i)); 
    i := v_my_associative_array.next(i); 
    end loop; 
end; 

的 「名字」 恰巧是1,2,3,等這裏(用大量聚集從而給出),你可能訪問 v_my_associative_array(1)實例。然而,在你的程序中,在數組中有一些可能的刪除操作之後,可能會有間隙,所以你不知道名爲1的元素是否存在以及元素4之前的元素是否是元素3.與批量收集元素的「名稱」沒有意義,您不會真正使用它們,而是通過所示的鏈條進行。

+0

感謝Thorsten對那種很好的描述。我真的很感激。 – 2014-12-03 12:40:00

+0

您應該添加最重要的區別:性能!爲正確的作業使用正確的工具!關聯數組總是像單個索引查找,而嵌套表像一個完整的表掃描。根據您的需要,其中一個將比另一個快得多! (我討厭甲骨文使用這種ambigous語法) – Falco 2014-12-03 12:52:09

+0

@Falco:我同意,語法讓我很困惑,所以經常。而且,對於給定的任務使用適當的集合也是正確的。但是,我認爲,與索引查找和全表掃描的類比有其缺陷。 v_my_nested_table(2)只是內存中的第二個元素,因此可以直接訪問,而v_my_associative_array(2)必須被查找。你是這個意思嗎? – 2014-12-03 13:10:45