PL/SQL VARRAY

Summary: in this tutorial, you will learn about the PL/SQL VARRAY and how to manipulate elements of a VARRAY effectively.

Introduction to PL/SQL VARRAY

VARRAY stands for the variable-sized array.

A VARRAY is single-dimensional collections of elements with the same data type. Unlike an associative array and nested table, a VARRAY always has a fixed number of elements(bounded) and never has gaps between the elements (not sparse).

Declare a VARRAY type

To declare a VARRAY type, you use this syntax:

TYPE type_name IS VARRAY(max_elements)
    OF element_type [NOT NULL];
Code language: SQL (Structured Query Language) (sql)

In this declaration:

  • type_name is the type of the VARRAY.
  • max_elements is the maximum number of elements allowed in the VARRAY.
  • NOT NULL specifies that the element of the VARRAY of that type cannot have NULL elements. Note that a VARRAY variable can be null, or uninitialized.
  • element_type is the type of elements of the VARRAY type’s variable.

To create a VARRAY type which is accessible globally in the database, not just in your PL/SQL code, you use the following syntax:

CREATE [OR REPLACE ] TYPE type_name AS | IS
    VARRAY(max_elements) OF element_type [NOT NULL];
Code language: SQL (Structured Query Language) (sql)

In this declaration, the OR REPLACE modifies existing type while keeping all existing grants of privileges.

Declare and initialize VARRAY variables

Once you created your own VARRAY type, you can declare a VARRAY instance of that type by referencing the VARRAY type. The basic syntax for VARRAY declaration is:

varray_name type_name [:= type_name(...)];Code language: SQL (Structured Query Language) (sql)

In this syntax:

  • The varray_name is the name of the VARRAY.
  • The type_name is the VARRAY type.
  • The type_name(...) is the constructor of the VARRAY type, which accepts a comma-separated list of elements as arguments. It has the same name as the VARRAY type.

Note that before using a VARRAY variable, you must initialize it. Otherwise, you will receive the following error:

ORA-06531: reference to uninitialized collection
Code language: SQL (Structured Query Language) (sql)

To initialize a VARRAY variable to an empty collection (zero elements), you use the following syntax:

varray_name type_name := type_name();Code language: SQL (Structured Query Language) (sql)

If you want to specify elements for the VARRAY variable while initializing it, you can use this syntax:

varray_name type_name := type_name(element1, element2, ...);Code language: SQL (Structured Query Language) (sql)

Accessing array elements

To access an array element you use the following syntax:

varray_name(n);Code language: SQL (Structured Query Language) (sql)

n is the index of the element, which begins with 1 and ends with the max_elements the maximum number of elements defined in the VARRAY type.

If n is not in the range (1, max_elements), PL/SQL raises the SUBSCRIPT_BEYOND_COUNT error.

PL/SQL VARRAY examples

Let’s take some examples of using VARRAY variables.

1) Simple PL/SQL VARRAY example

The following block illustrates a simple example of using VARRAY variables:

DECLARE
    TYPE t_name_type IS VARRAY(2) 
        OF VARCHAR2(20) NOT NULL;
    t_names t_name_type  := t_name_type('John','Jane');
    t_enames t_name_type := t_name_type();
BEGIN
    -- initialize to an empty array
    dbms_output.put_line("The number of elements in t_enames " || t_enames.COUNT);
    
    -- initialize to an array of a elements 
    dbms_output.put_line("The number of elements in t_names " || t_names.COUNT);
END;
/
Code language: SQL (Structured Query Language) (sql)

In this example:

First, declare a VARRAY of VARCHAR(2) with two elements:

TYPE t_name_type IS 
    VARRAY(2) OF VARCHAR2(20) NOT NULL;
Code language: SQL (Structured Query Language) (sql)

Next, declare a VARRAY variable and initialize it to a VARRAY of two elements:

t_names t_name_type  := t_name_type('John','Jane');
Code language: SQL (Structured Query Language) (sql)

Then, declare another VARRAY variable and initialize it to an empty array:

t_enames t_name_type := t_name_type();
Code language: SQL (Structured Query Language) (sql)

After that, use the COUNT method to get the number of elements in the VARRAY t_enames and display it.

dbms_output.put_line("The number of elements in t_enames " || t_enames.COUNT);
Code language: SQL (Structured Query Language) (sql)

Finally, use the same COUNT method to get the number of elements in the VARRAY t_names and print it out.

dbms_output.put_line("The number of elements in t_names " || t_names.COUNT);
Code language: SQL (Structured Query Language) (sql)

Note that you can assign a VARRAY to another using the following syntax:

varray_name := another_varray_name;
Code language: SQL (Structured Query Language) (sql)

For example:

t_enames := t_names;
Code language: SQL (Structured Query Language) (sql)

PL/SQL copies all members of t_names to t_enames.

2) PL/SQL VARRAY of records example

See the following example:

DECLARE
    TYPE r_customer_type IS RECORD(
        customer_name customers.NAME%TYPE,
        credit_limit customers.credit_limit%TYPE
    ); 
    
    TYPE t_customer_type IS VARRAY(2) 
        OF r_customer_type;

    t_customers t_customer_type := t_customer_type();
BEGIN
    t_customers.EXTEND;
    t_customers(t_customers.LAST).customer_name := 'ABC Corp';
    t_customers(t_customers.LAST).credit_limit  := 10000;
    
    t_customers.EXTEND;
    t_customers(t_customers.LAST).customer_name := 'XYZ Inc';
    t_customers(t_customers.LAST).credit_limit  := 20000;
    
    dbms_output.put_line('The number of customers is ' || t_customers.COUNT);
END;
/
Code language: SQL (Structured Query Language) (sql)

First, define a record type that includes two fields customer name and credit limit.

TYPE r_customer_type IS RECORD(
    customer_name customers.name%TYPE,
    credit_limit customers.credit_limit%TYPE
); 
Code language: SQL (Structured Query Language) (sql)

Next, declare a VARRAY type of the record r_customer_type with the size of two:

TYPE t_customer_type IS VARRAY(2) 
    OF r_customer_type;
Code language: SQL (Structured Query Language) (sql)

Then, declare a VARRAY variable of the VARRAY type t_customer_type:

t_customers t_customer_type := t_customer_type();
Code language: SQL (Structured Query Language) (sql)

After that, use the EXTEND method to add an instance to t_customers and the LAST method to append an element at the end of the VARRAY t_customers

t_customers.EXTEND;
t_customers(t_customers.LAST).customer_name := 'ABC Corp';
t_customers(t_customers.LAST).credit_limit  := 10000;
    
t_customers.EXTEND;
t_customers(t_customers.LAST).customer_name := 'XYZ Inc';
t_customers(t_customers.LAST).credit_limit  := 20000;
Code language: SQL (Structured Query Language) (sql)

Finally, use the COUNT method to get the number of elements in the array:

dbms_output.put_line('The number of customers is ' || t_customers.COUNT);
Code language: SQL (Structured Query Language) (sql)

Here is the output of the block:

The number of customers is 2
Code language: SQL (Structured Query Language) (sql)

3) Adding elements to VARRAY from a cursor example

The following example uses a cursor to retrieve five customers who have the highest credits from the customers table and add data to a VARRAY:

customers table
DECLARE
    TYPE r_customer_type IS RECORD(
        customer_name customers.name%TYPE,
        credit_limit customers.credit_limit%TYPE
    ); 

    TYPE t_customer_type IS VARRAY(5) 
        OF r_customer_type;
    
    t_customers t_customer_type := t_customer_type();

    CURSOR c_customer IS 
        SELECT NAME, credit_limit 
        FROM customers 
        ORDER BY credit_limit DESC 
        FETCH FIRST 5 ROWS ONLY;
BEGIN
    -- fetch data from a cursor
    FOR r_customer IN c_customer LOOP
        t_customers.EXTEND;
        t_customers(t_customers.LAST).customer_name := r_customer.name;
        t_customers(t_customers.LAST).credit_limit  := r_customer.credit_limit;
    END LOOP;

    -- show all customers
    FOR l_index IN t_customers .FIRST..t_customers.LAST 
    LOOP
        dbms_output.put_line(
            'The customer ' ||
            t_customers(l_index).customer_name ||
            ' has a credit of ' ||
            t_customers(l_index).credit_limit
        );
    END LOOP;

END;
/
Code language: SQL (Structured Query Language) (sql)

In this example:

First, declare a record type, a VARRAY type of the record with 5 elements, and a VARRAY variable of that VARRAY type:

TYPE r_customer_type IS RECORD(
    customer_name customers.name%TYPE,
    credit_limit customers.credit_limit%TYPE
); 

TYPE t_customer_type IS VARRAY(5) 
    OF r_customer_type;
    
t_customers t_customer_type := t_customer_type();
Code language: SQL (Structured Query Language) (sql)

Second, declare a cursor that retrieves 5 customers with the highest credits:

CURSOR c_customer IS 
    SELECT name, credit_limit 
    FROM customers 
    ORDER BY credit_limit DESC 
    FETCH FIRST 5 ROWS ONLY;
Code language: SQL (Structured Query Language) (sql)

Third, process the cursor and append each element to the VARRAY t_customers:

FOR r_customer IN c_customer LOOP
    t_customers.EXTEND;
    t_customers(t_customers.LAST).customer_name := r_customer.name;
    t_customers(t_customers.LAST).credit_limit  := r_customer.credit_limit;
END LOOP;Code language: SQL (Structured Query Language) (sql)

Finally, iterate over the elements of the VARRAY t_customers and print out the customer name and credit:

FOR l_index IN t_customers .FIRST..t_customers.LAST 
    LOOP
        dbms_output.put_line(
            'The customer ' ||
            t_customers(l_index).customer_name ||
            ' has a credit of ' ||
            t_customers(l_index).credit_limit
        );
    END LOOP;Code language: SQL (Structured Query Language) (sql)

Here is the output:

The customer General Mills has a credit of 179916.92
The customer NextEra Energy has a credit of 141953.76
The customer Southern has a credit of 127665.21
The customer Jabil Circuit has a credit of 113340.75
The customer Progressive has a credit of 94989.78
Code language: SQL (Structured Query Language) (sql)

Delete elements

To delete all elements of a VARRAY, you use the DELETE method:

varray_name.DELETE;Code language: SQL (Structured Query Language) (sql)

To remove one element from the end of a VARRAY, you use the TRIM method:

varray_name.TRIM;Code language: SQL (Structured Query Language) (sql)

To remove n elements from the end of a VARRAY, you use the TRIM(n) method:

varray_name.TRIM(n)Code language: SQL (Structured Query Language) (sql)

In this tutorial, you have learned about PL/SQL VARRAY and how to manipulate elements of a VARRAY effectively.

Was this tutorial helpful?