4

There are two links http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/composites.htm#LNPLS99981 and

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

by referring above two links i have two doubt

1.Which one is correct nested table?

2.If the oracle doc is correct what is the difference between nested table and associative array?

Community
  • 1
  • 1
Puneet Kushwah
  • 1,495
  • 2
  • 17
  • 35
  • Both are good. In a nutshell, associative arrays have an `INDEX BY` clause and nested tables don't. – Tony Andrews Dec 03 '14 at 10:27
  • 1
    If in the oracle document(the first link you've provided)you scroll up a little bit you'll see Table 5-1, which highlights differences and similarities between different collection types. – Nick Krasnov Dec 03 '14 at 11:13
  • 1
    Another important difference: You can create a nested table on database level and you can use them in a table as column type. With an associative array you cannot do this. – Wernfried Domscheit Dec 03 '14 at 12:11

2 Answers2

6

Here is another difference which is not that commonly known. You can compare two nested tables with = or <> but associative array you cannot.

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;

When you work with nested tables you can also use Multiset Operators, Multiset Conditions and SET which are not available for associative arrays.

Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
  • Thanks for the answer but As per my knowledge if we use associative array and put some values in it, it stores is sorted order not as we entered and by this i came to know that nested table also sort the data, but why the associative array is not able to compare as it also have some memory allocated in PGA? – Puneet Kushwah Dec 03 '14 at 12:49
  • @Wernfried: Thank you for the info. I didn't know that. So nested tables are treated as multisets when compared. Interesting. – Thorsten Kettner Dec 03 '14 at 12:59
  • @PuneetKushwah: I don't know why Oracle makes this difference. Maybe due to the fact that an associative array does not have a fixed size. – Wernfried Domscheit Dec 03 '14 at 13:25
  • I got my OCA certificate today but didn't got any Oracle Id Card can you tell me why? – Puneet Kushwah Dec 04 '14 at 10:16
5

A nested table is just an array of n elements.

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;

A nested table must be initialized as shown. It has zero elements at first. To add elements we use EXTEND. This nested table has 10 elements. They are indexed 1 to 10. Element 1 has the value 100. The others have value null. An access to a non-existent element, say the 11th element, raises an error.

An associative array on the other hand is an array of name/value pairs. Let's use numbers (pls_integer typically) for the naming:

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;

An associative array needs no initialization. It is empty and gets populated. Here we associate the element called 1 with the value 100 and the element with the name 11 with the value 1000. So there are two elements in the array. We get a no data found exception when we try to access a name that is not in the array.

We can also use strings for the names:

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;

You can use both collections to get table data, but you use them differently. The nested table has a count and you can just loop from 1 to count to access its elements:

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;

The associative array however must be read from whatever happens to be the first index to the next and next and next using FIRST and 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;

The "names" happen to be 1, 2, 3, etc. here (given thus by the bulk collection) and you could access v_my_associative_array(1) for instance. Later in your program, however, after some possible delete operations in the array, there may be gaps, so you don't know whether an element named 1 exists and whether the element before element 4 happens to be element 3. As with bulk collect the "names" for the elements have no meaning you would not really use them, but go instead through the chain as shown.

Thorsten Kettner
  • 89,309
  • 7
  • 49
  • 73
  • Thanks Thorsten for that kind of great description. I really appreciate that. – Puneet Kushwah Dec 03 '14 at 12:40
  • 1
    You should maybe add the most important difference: Performance! Use the right tool for the right JOB! Associative Arrays are always like single index-lookups, while Nested Tables work like a full table-scan. Depending on your needs, one of them will be much faster than the other! (I hate Oracle for using this ambigous syntax) – Falco Dec 03 '14 at 12:52
  • @Falco: I agree, that syntax had me confused so often yet. And you are also right as to using the appropriate collection for a given task. However your analogy with index lookup and full table scan has its flaws, I think. v_my_nested_table(2) is just the second element in memory and thus accessed directly, whereas v_my_associative_array(2) must be looked for. Is that what you mean? – Thorsten Kettner Dec 03 '14 at 13:10
  • @Falco: Are you sure about that? When you use them in memory then the difference should be insignificant - unless your Nested Table or Associative Array contains millions of entries. For data in a table such camparison does not apply, because you cannot store Associative Arrays in a table. – Wernfried Domscheit Dec 03 '14 at 13:31
  • @Wernfried I was wrong... I just ran some benchmarks and it seems 11g and 12c have almost no difference between accessing Nested Tables and associative arrays... With 12c you can even use SELECT-Queries on Associative Arrays! - So the single benefit of nested tables seems to be saving in the Database... – Falco Dec 03 '14 at 16:42
  • Oh and nested Tables can also become sparse - so you should always loop over them with FIRST + NEXT, or you can get NO_DATA_FOUND – Falco Dec 03 '14 at 16:45