2014-12-03 84 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