Varrays in PL/SQL: Syntax, Examples, and Use Cases for Oracle Collections
Varrays in PL/SQL (Variable-size Arrays) are bounded, one-dimensional collections that allow the storage of a fixed number of elements of the same data type. This guide explains how to define, use, and manipulate Varrays in PL/SQL through examples, covering declaration, object types, DML integration, and best practices.
What Are Varrays in PL/SQL?
Varrays (or VARYING ARRAYs) are a type of collection that store a fixed number of elements. They are ideal when the maximum size of the collection is known beforehand. In Oracle, Varrays are indexed starting from 1 and can be used in PL/SQL blocks, object types, and as column data types in tables.
Syntax for Declaring Varrays
TYPE type_name IS VARRAY(size_limit) OF element_type [NOT NULL];
type_name
: Name of the Varray type.size_limit
: Maximum number of elements.element_type
: Oracle data type (e.g., INTEGER, VARCHAR2).NOT NULL
(optional): Disallows nulls in the array.
Initializing and Using Varrays
DECLARE
TYPE integer_varray IS VARRAY(3) OF INTEGER;
varray_integer INTEGER_VARRAY := integer_varray(NULL, NULL, NULL);
BEGIN
FOR i IN 1..3 LOOP
DBMS_OUTPUT.PUT_LINE('Integer Varray [' || i || '] = ' || varray_integer(i));
END LOOP;
varray_integer(1) := 11;
varray_integer(2) := 12;
varray_integer(3) := 13;
DBMS_OUTPUT.PUT_LINE(CHR(10) || 'Updated Varray Values:');
FOR i IN 1..3 LOOP
DBMS_OUTPUT.PUT_LINE('Integer Varray [' || i || '] = ' || varray_integer(i));
END LOOP;
END;
/
Using EXTEND Method and Collection API
DECLARE
TYPE integer_varray IS VARRAY(3) OF INTEGER;
varray_integer INTEGER_VARRAY := integer_varray();
BEGIN
FOR i IN 1..3 LOOP
varray_integer.EXTEND;
varray_integer(i) := 10 + i;
END LOOP;
FOR i IN 1..3 LOOP
DBMS_OUTPUT.PUT_LINE('Integer Varray [' || i || '] = ' || varray_integer(i));
END LOOP;
END;
/
Defining Varrays as Object Types
CREATE OR REPLACE TYPE integer_varray AS VARRAY(3) OF INTEGER;
/
DECLARE
varray_integer INTEGER_VARRAY := integer_varray(NULL, NULL, NULL);
BEGIN
FOR i IN 1..3 LOOP
varray_integer(i) := 10 + i;
END LOOP;
END;
/
Handling Null Values in Varrays
CREATE OR REPLACE TYPE integer_varray AS VARRAY(100) OF INTEGER NOT NULL;
/
DECLARE
varray_integer INTEGER_VARRAY := integer_varray();
BEGIN
FOR i IN 1..varray_integer.LIMIT LOOP
varray_integer.EXTEND;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Integer Varray Initialized [' || varray_integer.COUNT || ']');
END;
/
Varrays as Column Data Types in Tables
CREATE OR REPLACE TYPE address_varray AS VARRAY(3) OF VARCHAR2(30 CHAR);
/
CREATE TABLE addresses (
address_id INTEGER NOT NULL,
individual_id INTEGER NOT NULL,
street_address ADDRESS_VARRAY NOT NULL,
city VARCHAR2(20 CHAR),
state VARCHAR2(20 CHAR),
postal_code VARCHAR2(20 CHAR),
country_code VARCHAR2(10 CHAR),
CONSTRAINT address_pk PRIMARY KEY (address_id)
);
DML Operations with Varrays
INSERT INTO addresses VALUES (
11, 11,
address_varray('Office of Senator McCain', '450 West Paseo Redondo', 'Suite 200'),
'Tucson', 'AZ', '85701', 'USA'
);
CREATE OR REPLACE TYPE varray_nested_table IS TABLE OF VARCHAR2(30 CHAR);
/
SELECT column_value
FROM THE (
SELECT CAST(street_address AS varray_nested_table)
FROM addresses
WHERE address_id = 11
);
UPDATE addresses
SET street_address = address_varray('Office of Senator McCain', '2400 E. Arizona Biltmore Cir.', 'Suite 1150')
WHERE address_id = 11;
DECLARE
TYPE address_type IS RECORD (
address_id INTEGER,
individual_id INTEGER,
street_address ADDRESS_VARRAY,
city VARCHAR2(20 CHAR),
state VARCHAR2(20 CHAR),
postal_code VARCHAR2(20 CHAR),
country_code VARCHAR2(10 CHAR)
);
address address_type;
CURSOR get_address(id INTEGER) IS
SELECT * FROM addresses WHERE address_id = id;
BEGIN
OPEN get_address(11);
FETCH get_address INTO address;
CLOSE get_address;
address.street_address(1) := 'Office of Senator John McCain';
UPDATE addresses
SET street_address = address.street_address
WHERE address_id = 11;
END;
/
Best Practices for Using Varrays
Use Varrays when the number of elements is known and fixed.
Avoid Varrays for frequently updated structures โ use Nested Tables instead.
Disallow nulls to avoid logic issues and data gaps.
Use EXTEND carefully to allocate memory for dynamic initialization.
Avoid querying Varray columns directly โ use
CAST
with nested tables.Prefer schema-level Varray types for reusability.
AmantPoint Exclusive Learning Series
ยฉ 2025 AmantPoint. All rights reserved. Educational content for developers and learners.