1. Home
  2. Docs
  3. Oracle to PostgreSQL Migration
  4. PLSQL to plpgsql
  5. Migrate Oracle Collections to PostgreSQL

Migrate Oracle Collections to PostgreSQL

Oracle PL/SQL offers three kinds of collections: Associative Arrays, Nested Tables, and Varrays (short for variable-size arrays). Nested tables extend the functionality of associative arrays (formerly called PL/SQL tables or index-by tables).

Migrate Associative Array

The Associative arrays were known as PL/SQL tables in Oracle 7, and index-by tables in Oracle 8 and 8i. The name was changed to Associative arrays in Oracle 9i.

This article demonstrates different usages of an associative array in Oracle and how to migrate the features in PostgreSQL.

OraclePostgreSQL
SET SERVEROUTPUT ON;
DECLARE
  TYPE dcm_test IS TABLE OF NUMBER   -- Associative array type 
    INDEX BY PLS_INTEGER;            --  indexed by integer
  
  testArray  dcm_test;        -- Associative array variable
  
BEGIN
  -- Add elements (key-value pairs) to associative array:
 
  testArray(1)  := 1000;
  testArray(2)  := 50000;
  testArray(3)  := 1750000;
 
  -- Change value for index 2
  testArray(2) := 88880;
 
  -- Print associative array:
  FOR i IN testArray.FIRST .. testArray.LAST LOOP
    DBMS_Output.PUT_LINE('Array (' || i || ') = ' || testArray(i));
  END LOOP;
END;
/

Output:

Array (1) = 1000
Array (2) = 88880
Array (3) = 1750000

PL/SQL procedure successfully completed.

SET client_min_messages = debug;
DO $$
DECLARE
  -- Declare array  
  testArray  INTEGER[];   -- Array variable declaration

BEGIN
  -- Add elements (key-value pairs) to associative array:
 
  testArray[1]  := 1000;
  testArray[2]  := 50000;
  testArray[3]  := 1750000;
 
  -- Change value associated with key 'Smallville':
  testArray[2] := 88880;
 
  -- Print associative array:
  FOR i IN array_lower(testArray, 1) .. array_upper(testArray, 1) LOOP
    RAISE DEBUG USING message := concat_ws('', 'Array (', i, ') = ', testArray[i]);
  END LOOP;
END $$;

Output:

DEBUG:  Array (1) = 1000
DEBUG:  Array (2) = 88880
DEBUG:  Array (3) = 1750000
DO

Migrate Nested Table

Nested tables are an extension of the associative arrays. The main difference between the two is that nested tables can be stored in a database column but associative arrays cannot. In addition some DML operations are possible on nested tables when they are stored in the database. During creation nested tables are dense, having consecutive subscripts for the elements. Once created elements can be deleted using the DELETE method to make the collection sparse. The NEXT method overcomes the problems of traversing sparse collections.

In order to use nested tables in PL/SQL block for rows processing, these steps must be followed.

  • When you declare a nested table variable, it must be initialized. You must initialize it, either by making it empty or by assigning a non-NULL value to it. An uninitialized nested table variable is a null collection. Any operation (except EXISTS operation) on an uninitialized nested table wil throw “ORA-06531: Reference to uninitialized collection” error.
  • To add an element to a nested table, you first use the EXTEND method to allocate memory to nested table.

This article demonstrates different usages of nested tables in Oracle and how to migrate the features in PostgreSQL.

OraclePostgreSQL

Below program declares a varray of size 3, is initialized and extended to store elements.

DECLARE
  TYPE dcm_test IS VARRAY(3) OF NUMBER;   -- Varray type
  testArray  dcm_test   := dcm_test();    -- Varray variable

BEGIN
  -- Add elements (key-value pairs) to VARRAY:
   testArray.EXTEND(3);

  testArray(1)  := 1000;
  testArray(2)  := 50000;
  testArray(3)  := 1750000;
 
  -- Change value for index 2
  testArray(2) := 88880;
 
  -- Print associative array:
  FOR i IN testArray.FIRST .. testArray.LAST LOOP
    DBMS_Output.PUT_LINE('Array (' || i || ') = ' || testArray(i));
  END LOOP;
END;
/

Output:

Array (1) = 1000
Array (2) = 88880
Array (3) = 1750000

PL/SQL procedure successfully completed.

Postgres provides arrays which are powerful feature and conceptually resemble Oracle varrays in all aspects.

SET client_min_messages = debug;
DO $$
DECLARE
  -- Declare array  
  testArray  INTEGER[];   -- Array variable declaration

BEGIN
  -- Add elements (key-value pairs) to associative array:
 
  testArray[1]  := 1000;
  testArray[2]  := 50000;
  testArray[3]  := 1750000;
 
  -- Change value associated with key 'Smallville':
  testArray[2] := 88880;
 
  -- Print associative array:
  FOR i IN array_lower(testArray, 1) .. array_upper(testArray, 1) LOOP
    RAISE DEBUG USING message := concat_ws('', 'Array (', i, ') = ', testArray[i]);
  END LOOP;
END $$;

Output:

DEBUG:  Array (1) = 1000
DEBUG:  Array (2) = 88880
DEBUG:  Array (3) = 1750000
DO
Was this article helpful to you? Yes No

How can we help?