PL/SQL Collections

A collection is an ordered group of elements, all of the same type — PL/SQL's answer to an array or a list. There are three kinds, and choosing the right one comes down to two questions: does it need to be stored in a database column, and does it need a fixed maximum size?
KindIndexed bySizeStored in a column?
Associative arrayPLS_INTEGER or VARCHAR2, any values, need not be contiguousUnboundedNo — PL/SQL memory only
Nested tableSequential integers starting at 1UnboundedYes
VARRAYSequential integers starting at 1Fixed maximum, set at declarationYes

Associative Arrays

Also called an "index-by table". It behaves like a hash map: any key maps directly to a value, with no need to EXTEND or pre-size it. It exists only for the life of the PL/SQL block or session — it cannot be a column type.

Example:

declare
  type t_scores is table of number index by pls_integer;
  scores t_scores;
  idx pls_integer;
begin
  scores(1)   := 90;
  scores(100) := 60; -- keys need not be contiguous

  idx := scores.first;
  while idx is not null loop
    dbms_output.put_line('scores(' || idx || ') = ' || scores(idx));
    idx := scores.next(idx);
  end loop;
end;
/

Nested Tables

An unbounded, ordered collection that can be a column type or a table type on its own. It starts uninitialized (NULL) until you call its constructor, and grows one slot at a time with EXTEND.

Example:

declare
  type t_names is table of varchar2(20);
  names t_names := t_names(); -- constructor call, now it is an empty table
begin
  names.extend(2);
  names(1) := 'Ana';
  names(2) := 'Bob';

  for i in 1 .. names.count loop
    dbms_output.put_line('names(' || i || ') = ' || names(i));
  end loop;
end;
/

VARRAYs

A "variable-size array" — same idea as a nested table, but with a maximum capacity fixed at declaration. Use it when the upper bound is a known, small, business-meaningful number (a calendar's 12 months, a podium's top 3).

Example:

declare
  type t_top3 is varray(3) of varchar2(20);
  top3 t_top3 := t_top3();
begin
  top3.extend(3);
  top3(1) := 'Gold';
  top3(2) := 'Silver';
  top3(3) := 'Bronze';
  -- top3.extend(1) here would raise ORA-06532: subscript outside limit

  for i in 1 .. top3.count loop
    dbms_output.put_line('top3(' || i || ') = ' || top3(i));
  end loop;
end;
/

Collection Methods

MethodWhat it does
.COUNTNumber of elements currently in the collection.
.FIRST / .LASTLowest / highest index in use.
.NEXT(n) / .PRIOR(n)Next / previous index after/before n — essential for sparse associative arrays.
.EXISTS(n)True if index n has a value.
.EXTEND(n)Grow a nested table or VARRAY by n slots (default 1).
.DELETE(n)Remove the element at index n (or every element, with no argument).

See it in a full demo: Demo 14 — Collections.