嵌套数组和关联数组有什么区别?

时间:2014-12-03 09:57:30

标签: sql oracle plsql associative-array nested-table

有两个链接 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.哪一个是正确的嵌套表?

2.如果oracle doc正确,嵌套表和关联数组之间的区别是什么?

2 个答案:

答案 0 :(得分:4)

这是另一个不为人所知的区别。您可以将两个嵌套表与=<>进行比较,但不能将关联数组进行比较。

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

答案 1 :(得分: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循环到count来访问它的元素:

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.与批量收集一样元素的“名称”没有意义,你不会真正使用它们,而是通过如图所示的链来。