ORA-06531: Reference to Uninitialized Collection
ORA-06531 is a PL/SQL runtime error that occurs when you try to use a collection variable (Nested Table, VARRAY, or Associative Array) that has been declared but never initialized. In Oracle PL/SQL, simply declaring a collection variable leaves it in a NULL state — which is fundamentally different from an empty collection — and any attempt to call collection methods or access elements on a NULL collection immediately raises this error.
Top 3 Causes
1. Using a Collection Without Calling Its Constructor
The most common cause: declaring a Nested Table or VARRAY and then calling .EXTEND or accessing an element without first calling the constructor.
-- BAD: Raises ORA-06531
DECLARE
TYPE num_list IS TABLE OF NUMBER;
v_nums num_list;
BEGIN
v_nums.EXTEND; -- ORA-06531 here!
v_nums(1) := 42;
END;
/
-- GOOD: Initialize with constructor first
DECLARE
TYPE num_list IS TABLE OF NUMBER;
v_nums num_list;
BEGIN
v_nums := num_list(); -- Initialize as empty collection
v_nums.EXTEND;
v_nums(1) := 42;
DBMS_OUTPUT.PUT_LINE('Value: ' || v_nums(1));
END;
/
2. Conditional Branches That Skip Initialization
When a collection is only initialized inside one branch of an IF statement, any code path that skips that branch will leave the collection NULL.
-- BAD: Initialization skipped when dept_id = 20
DECLARE
TYPE name_list IS TABLE OF VARCHAR2(100);
v_names name_list;
v_dept NUMBER := 20;
BEGIN
IF v_dept = 10 THEN
v_names := name_list('King', 'Blake');
END IF;
DBMS_OUTPUT.PUT_LINE(v_names.COUNT); -- ORA-06531 if dept = 20!
END;
/
-- GOOD: Pre-initialize before any branch
DECLARE
TYPE name_list IS TABLE OF VARCHAR2(100);
v_names name_list := name_list(); -- Safe default
v_dept NUMBER := 20;
BEGIN
IF v_dept = 10 THEN
v_names := name_list('King', 'Blake');
ELSIF v_dept = 20 THEN
v_names := name_list('Jones', 'Ford');
END IF;
IF v_names IS NOT NULL THEN
DBMS_OUTPUT.PUT_LINE('Count: ' || v_names.COUNT);
END IF;
END;
/
3. Uninitialized OUT Parameter Collections in Subprograms
When a collection is passed as an OUT parameter, the subprogram receives it as NULL. Failing to initialize it inside the procedure before use causes ORA-06531.
-- Schema-level type
CREATE OR REPLACE TYPE id_table IS TABLE OF NUMBER;
/
-- BAD: No initialization inside procedure
CREATE OR REPLACE PROCEDURE fetch_ids_bad (p_ids OUT id_table) IS
BEGIN
p_ids.EXTEND; -- ORA-06531!
p_ids(1) := 99;
END;
/
-- GOOD: Initialize the OUT parameter first
CREATE OR REPLACE PROCEDURE fetch_ids_good (p_ids OUT id_table) IS
BEGIN
p_ids := id_table(); -- Must initialize here
SELECT department_id
BULK COLLECT INTO p_ids
FROM departments
WHERE rownum <= 3;
END;
/
-- Caller
DECLARE
v_ids id_table;
BEGIN
fetch_ids_good(v_ids);
FOR i IN 1 .. v_ids.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('ID: ' || v_ids(i));
END LOOP;
END;
/
Quick Fix Solutions
-
Always call the constructor before using any Nested Table or VARRAY:
v_col := collection_type(); -
Initialize at declaration time to eliminate risk:
v_col collection_type := collection_type(); - Add a NULL guard before accessing any collection received from external sources:
IF v_collection IS NULL THEN
v_collection := your_collection_type();
END IF;
- Use BULK COLLECT where possible — it automatically handles collection population and works on pre-initialized collections cleanly.
Prevention Tips
-
Establish a coding standard: Always initialize collection variables at the point of declaration in the
DECLAREsection. This single rule eliminates the vast majority of ORA-06531 occurrences before they happen. -
Write unit tests for edge cases: Use a framework like utPLSQL to cover scenarios where collections might be NULL, especially for procedures with
OUTparameters. Catching these issues in testing is far cheaper than fixing them in production.
Related Errors
| Error Code | Description |
|---|---|
| ORA-06530 | Reference to uninitialized composite (Object Types) |
| ORA-06532 | Subscript outside of limit (VARRAY max size exceeded) |
| ORA-06533 | Subscript beyond count (index exceeds element count) |
📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.
Top comments (0)