To use collections in an application, you define one or more PL/SQL types, then define variables of those types. You can define collection types in a procedure, function, or package. You can pass collection variables as parameters, to move data between client-side applications and stored subprograms. To look up data that is more complex than single values, you can store PL/SQL records or SQL object types in collections. Nested tables and varrays can also be attributes of object types.
Defining Collection Types
To create collections, you define a collection type, then declare variables of that type. You can define TABLE and VARRAY types in the declarative part of any PL/SQL block, subprogram, or package.
For associative arrays (also known as index-by tables), use the syntax:
TYPE type_name IS TABLE OF element_type [NOT NULL]
INDEX BY key_type;
The key_type can be numeric, either BINARY_INTEGER or PLS_INTEGER. It can also be VARCHAR2 or one of its subtypes VARCHAR, STRING, or LONG. You must specify the length of a VARCHAR2-based key, except for LONG which is equivalent to declaring a key type of VARCHAR2(32760). The types RAW, LONG RAW, ROWID, CHAR, and CHARACTER are not allowed as keys for an associative array.
For nested tables, use the syntax:
TYPE type_name IS TABLE OF element_type [NOT NULL];
type_name is a type specifier used later to declare collections. For nested tables declared within PL/SQL, element_type is any PL/SQL datatype except REF CURSOR.
For varrays, use the syntax:
TYPE type_name IS {VARRAY | VARYING ARRAY} (size_limit)
OF element_type [NOT NULL];
The meanings of type_name and element_type are the same as for nested tables. size_limit is a positive integer literal representing the maximum number of elements in the array. When defining a VARRAY type, you must specify its maximum size.
Defining Collection Variables
Once you define a collection type, you can declare variables of that type. You use the new type name in the declaration, the same as with predefined types such as NUMBER and INTEGER.
Example: Declaring Nested Tables, Varrays, and Associative Arrays
DECLARE
TYPE nested_type IS TABLE OF VARCHAR2(20);
TYPE varray_type IS VARRAY(50) OF INTEGER;
TYPE associative_array_type IS TABLE OF NUMBER
INDEXED BY BINARY_INTEGER;
v1 nested_type;
v2 varray_type;
v3 associative_array_type;
v4 v1%TYPE;
TYPE EmpList IS TABLE OF emp.ename%TYPE; -- based on column
CURSOR c1 IS SELECT * FROM dept;
TYPE DeptFile IS VARRAY(20) OF c1%ROWTYPE; -- based on cursor
TYPE AnEntry IS RECORD (
term VARCHAR2(20),
meaning VARCHAR2(200));
TYPE Glossary IS VARRAY(250) OF AnEntry;
TYPE EmpList IS TABLE OF emp.empno%TYPE NOT NULL;
Example: Declaring a Procedure Parameter as a Nested Table
You can declare collections as the formal parameters of functions and procedures. That way, you can pass collections to stored subprograms and from one subprogram to another. The following example declares a nested table as a parameter of a packaged procedure:
CREATE PACKAGE personnel AS
TYPE Staff IS TABLE OF Employee;
...
PROCEDURE award_bonuses (members IN Staff);
END personnel;
You can also specify a collection type in the RETURN clause of a function specification:
DECLARE
TYPE SalesForce IS VARRAY(25) OF Salesperson;
FUNCTION top_performers (n INTEGER) RETURN SalesForce IS ...
Initializing and Referencing Collections
Until you initialize it, a nested table or varray is atomically null: the collection itself is null, not its elements. To initialize a nested table or varray, you use a constructor, a system-defined function with the same name as the collection type. This function "constructs" collections from the elements passed to it.
You must explicitly call a constructor for each varray and nested table variable. (Associative arrays, the third kind of collection, do not use constructors.) Constructor calls are allowed wherever function calls are allowed.
Example: Constructor for a Nested Table and a Varray
DECLARE
TYPE CourseList IS TABLE OF VARCHAR2(16);
my_courses CourseList;
TYPE ProjectList IS VARRAY(50) OF VARCHAR2(16);
accounting_projects ProjectList;
BEGIN
my_courses :=
CourseList('Econ 2010', 'Acct 3401', 'Mgmt 3100');
accounting_projects :=
ProjectList('Expense Report', 'Outsourcing', 'Auditing');
END;
Referencing Collection Elements
Every reference to an element includes a collection name and a subscript enclosed in parentheses. The subscript determines which element is processed. To reference an element, you specify its subscript using the syntax
collection_name(subscript)
where subscript is an expression that yields an integer in most cases, or a VARCHAR2 for associative arrays declared with strings as keys.
The allowed subscript ranges are:
- For nested tables, 1 .. 2**31.
- For varrays, 1 .. size_limit, where you specify the limit in the declaration.
- For associative arrays with a numeric key, -2**31 .. 2**31.
- For associative arrays with a string key, the length of the key and number of possible values depends on the VARCHAR2 length limit in the type declaration, and the database character set.
This example shows how to reference an element in the nested table NAMES:
DECLARE
TYPE Roster IS TABLE OF VARCHAR2(15);
names Roster := Roster('J Hamil', 'D Caruso', 'R Singh');
BEGIN
FOR i IN names.FIRST .. names.LAST
LOOP
IF names(i) = 'J Hamil' THEN
NULL;
END IF;
END LOOP;
END;
Assigning Collections
One collection can be assigned to another by an INSERT, UPDATE, FETCH, or SELECT statement, an assignment statement, or a subprogram call.
You can assign the value of an expression to a specific element in a collection using the syntax:
collection_name(subscript) := expression;
where expression yields a value of the type specified for elements in the collection type definition.
Comparing Collections
You can check whether a collection is null, but not test whether two collections are the same. Conditions such as greater than, less than, and so on are also not allowed.