1/2

Live Webinar: Building a Complete Migration Roadmap | Join here

2/2

Meet SQLWays AI Assistant | Learn more

Migrate Oracle to PostgreSQL

Ispirer Toolkit is purpose-built for Oracle to PostgreSQL migration — automating schema conversion, business logic transfer, and data migration so your team can focus on what matters. Moving from Oracle to PostgreSQL for cost savings, cloud readiness, or vendor independence? Trust a team who’s done it hundreds of times.

Make the most of automated migration to focus on your business core.

Get free consultation

Many companies have used our tools and provided excellent feedback on their performance

1000+ companies including Fortune 500 and Global 2000 use Ispirer solutions. Join the champions.

Paul Wurth
Epicor
ndex
Toyota
NTT Data
Continental Rubber Company
Bloxs
Staples
Ned Graphics
Cardinal Health
HCLTech
demantec
Autobacs
loxon
Magnit
Canada Helps Org
University Of Maryland
Utah State University
WorldLine
Beckman Coulter
Comtron
E-Tabs
PrimeBank Kenya
Paul Group
Visma
Indra
Reply Technology
Eaton
Safran

Migration opportunities with Ispirer

Ispirer Ecosystem automates your migration routine to enable quick and smart transformation of any database. Double the migration speed with our comprehensive solutions.

Ispirer Toolkit only

Ispirer Toolkit + Service

With Ispirer Toolkit only

  • Free InsightWays tool to analyze your Oracle database and estimate migration complexity
  • Assistance in Ispirer Toolkit configuration
  • Automated migration of database schema, tables, SQL objects, business logic, and data
  • Timely customization of the Ispirer Toolkit to maximize automation rate
  • Expert support
Get started — it’s free

Trial is free. No payment

Ispirer Toolkit only

With Ispirer Toolkit as a part of migration service

  • Detailed analysis of your Oracle database and tailored migration roadmap
  • Migration of data and database schema, incl. SQL objects, business logic, tables
  • Team of database conversion experts and a dedicated Project Manager
  • Regular updates on the project status
  • Post-migration refinement and testing
Get started — it’s free

Trial is free. No payment

Ispirer Toolkit + Service

Our modernization and migration approach

We select the right conversion approach based on business specifics, project scope, complexity, and risk profile.

  • Rule-Based

    Deterministic conversion

    Engine

    SQLWays, CodeWays

    Automation & coverage

    ~70–80% automated coverage out of the box, with the option to reach up to 90% through manual refinement, refactoring, validation, and QA

    What you get

    Predictable scope and timeline, stable and repeatable output

    Best for

    Well-defined, structured migrations

  • Recommended

    Hybrid

    Rules + AI-assisted refinement

    Engine

    SQLWays, CodeWays + AI

    Automation & coverage

    ~70–80% automated coverage, up to 90% with AI, reducing manual conversion, validation, and testing

    What you get

    Predictability of the rule-based engine + speed of AI, backed by the Ispirer expert framework

    Best for

    Complex or partially undocumented systems

  • AI-Driven

    AI-led analysis and delivery

    Engine

    AI engine

    Automation & coverage

    AI-led code and business logic extraction by Ispirer Migration Experts

    What you get

    AI-assisted refactoring, code generation and documentation, human-led QA, insights into undocumented logic and target design

    Best for

    Iterative modernization and innovation-driven transformation

The approach is defined during the Discovery Phase, based on business specifics, source system complexity, target state, timeline, and expected business value.

Ispirer Ecosystem for automated migration

Ispirer Toolkit is a solution for automated heterogeneous database migration. Using it, you can transfer tables and data, stored procedures, functions, packages, views, and triggers. This solution is based on an intelligent proprietary algorithm that analyzes data types, relationships between objects, reserved words, and code structures that do not have equivalents in a target technology.

AI-powered SQLWays

Schema migration

Ispirer Systems is an ISO/IEC 27001 certified organization. We adhere to the highest international standards of information security.

iso 27001 certification

Oracle to PostgreSQL migration steps

A proven end-to-end approach that turns complex Oracle-to-PostgreSQL migration into a clear, manageable process.

Connect Ispirer's free InsightWays tool to your Oracle database. It collects a full inventory of objects, structures, and statements, then produces a complexity report. This is your Oracle to Postgres migration checklist baseline — you know exactly what needs to be converted, what can be automated, and what will need manual review.
SCOPE DEFINED

Configure the target PostgreSQL environment — whether on-premises, Google Cloud SQL, Amazon RDS, or Azure Database. Establish read-only access to the source Oracle database. No changes are made to the source system at any point.
ENVIRONMENT READY

Ispirer Toolkit converts the full database schema: tables, indexes, constraints, views, sequences, triggers, stored procedures, functions, and packages. PL/SQL is automatically converted to PL/pgSQL. Oracle-specific constructs — including hierarchical queries (CONNECT BY), dynamic SQL, collections, and native packages — are handled by the toolkit's rule engine.

Where automation hits a limit, Ispirer engineers add custom conversion rules, typically within 3–5 business days.

LOGIC CONVERTED

Embedded SQL and database API calls in your application code are rewritten to target PostgreSQL syntax. Where Oracle packages or stored procedures are better moved out of the database entirely, Ispirer migrates that business logic to the application layer (Java, C#, Python, etc.).
CODE UPDATED

Migrated databases are tested against source Oracle test cases using function calls, queries, and data snapshots. Discrepancies are analyzed and corrected. For databases without existing test cases, Ispirer develops testing scenarios based on database logic.
MIGRATION VALIDATED

Query plans and database settings are tuned for PostgreSQL. Operations optimized for Oracle do not automatically perform the same way in PostgreSQL — this step ensures the target database performs at production level.
PERFORMANCE TUNED

Data is migrated without middleware, without altering the source, and without requiring unique columns. For large-scale workloads where downtime windows are tight, preliminary cold-data migration is performed ahead of the production cutover to minimize the final switch time.
DATA MIGRATED

Production database migration is executed. The application is switched to the new PostgreSQL database. Ispirer provides post-cutover support to resolve any remaining issues and confirm system stability.
CUTOVER COMPLETE
Migration Steps

Migrate Smarter. Evolve Faster

Over 150 migration directions
Give it a try now. Book a demo

Dive into tool’s features

  • PostgreSQL
  • Oracle
  • AlloyDB
  • SQL Server
  • Informix
  • MySQL
  • DB2
  • MariaDB
  • Sybase ASE
  • PostgreSQL
  • Oracle
  • AlloyDB
  • SQL Server
  • Informix
  • MySQL
  • DB2
  • MariaDB
  • Sybase ASE
  • MSSQL
  • COBOL
  • Azure
  • Progress 4GL
  • SAP
  • PowerBulder
  • .NET
  • Delphi
  • MSSQL
  • COBOL
  • Azure
  • Progress 4GL
  • SAP
  • PowerBulder
  • .NET
  • Delphi

Designed for continuity

Every old system carries years of decisions inside it, some good, some made under pressure nobody remembers anymore. My team's job is to understand that history well enough to carry forward what actually works, instead of throwing it out and starting over. That's what I find genuinely interesting about this work: nothing gets lost just because it's old, it either keeps running or turns into something better.

Yuri Koran CTO, Ispirer Systems

Photo of Yuri Koran, CTO of Ispirer Systems

Cloud migration software

Ispirer Toolkit facilitates seamless database migration to both on-premises and cloud environments. This includes Oracle to PostgreSQL migration, with full support for Google Cloud SQL, Amazon RDS, Oracle Cloud Infrastructure, and Azure Database.

Move your migration project to the next level. Migrate logic from database to application

Ispirer has a solution to unlock the full potential of your database. Our team helps you to move business logic to an application layer seamlessly to advance the database performance.

Source Database

  • Oracle
Read-only access

ODBC

Files With Business Logic SQL Code

  • Oracle
How Migration work

Seamless integration, limitless possibilities!

Application Target Code

  • Java
  • JDBC
  • Spring
  • Hibernate
  • Automated conversion of SQL objects to application code. Ispirer Ecosystem supports Oracle, SQL Server, Sybase, PostgreSQL, Java, etc.
  • In case of changing the RDBMS, embedded SQL will be automatically rewritten to adhere to the syntax of the new database.
  • Migration with or without connection to databases. Both options allow you to successfully migrate business logic from the database to the application layer. However, connecting to the database allows the migration tool to take into account additional data from the database and helps improve the conversion.

Unlock agility: shift your database logic to the application layer!

Transform faster, scale smarter—see how moving from database to application layer drives real results. Let’s modernize it together.

Learn more

Explore our comprehensive migration solutions

The world’s most innovative companies are building their next big thing with Ispirer

Magnit, CardinalHealth, Worldline and more have adopted SQLWays to boost their innovation life-cycle accelerate and manage their end-to-end innovation lifecycle

Magnit logo
CardinalHealth logo
WorldLine logo
Utah state university logo
Paul Group logo
Ndex Systems logo

Oracle to PostgreSQL MS SQL Server to PostgreSQL

Migration project

50%

Migration time reduction

1.365K

Lines of SQL code

8 Tb

of data

Talent Management

"Ispirer Toolkit enabled a seamless migration of 8 TB of data and 1.36M lines of code from Oracle and SQL Server to PostgreSQL. The automation features reduced migration time by 50%, cutting costs and minimizing manual effort. The quality, precision, and support exceeded our expectations."

SQL Server to PostgreSQL

Migration project

70%

Migration time reduction

650K+

Lines of SQL code

700+ tables

of data

Healthcare Solutions

"Ispirer helped us migrate 700+ tables and 650+ stored procedures from SQL Server to PostgreSQL, reducing development time by 60%-70%. The tool efficiently handled case-sensitive issues and frequent data changes. The excellent support made the process easy, fast, and effective."

Oracle 19c to PostgreSQL

Migration project

65%

Migration time reduction

1.500K

Lines of code

8 TB

of data

Payments & Financial Services

"Ispirer Toolkit helped us migrate 1.5 million lines of complex Oracle code to PostgreSQL, overcoming unique challenges with expert support. Their team provided customized solutions for a smooth transition. This migration is a key step in our cloud strategy, and we highly recommend Ispirer's services."

Informix to Oracle

Migration project

78%

Migration time reduction

200K+

Lines of code

12 TB

of data

Governmental

"Ispirer MnMTK was crucial to our successful database migration, converting 12 TB of data and 200,000 lines of SQL code. The tool outperformed other solutions, saving us countless hours. The support team was responsive and effective—money well spent."

Firebird to PostgreSQL

Migration project

55%

Migration time reduction

25K+

Lines of SQL code

> 150 tables

per database

Manufacturing & Fleet Management

"Ispirer's Toolkit enabled the efficient migration of 150 tables and 25,000 lines of code from Firebird to PostgreSQL. The tool saved us time and reduced risks, while the Ispirer team provided excellent support throughout. Highly recommended for similar database migration projects."

Sybase to MySQL

Migration project

95%

Migration time reduction

4.000+

Stored procedures

200+

tables

IT Services

"Ispirer’s tool allowed us to automatically convert 4,000+ procedures and 200+ tables from Sybase to MySQL with 95% success, saving a lot of time. The ability to customize the tool and the excellent support made the process smooth and efficient. Highly recommended!"

All testimonials

Migration details overview

Ispirer Toolkit automates the entire migration of database objects from Oracle to PostgreSQL.

  • Two ways to migrate your database

    1

    Ispirer Toolkit automates the entire migration of database objects from Oracle to PostgreSQL.

    recommended
    2

    Convert files containing Oracle PL/SQL scripts without connecting directly to the source database.

  • Ispirer Toolkit migrates the following objects

    views tables functions triggers procedures sequences packages collection and object types

    As a result, each separate database object is converted to its equivalent in PostgreSQL.

If you have your own applications, the embedded SQL and database APIs can be converted using either Ispirer Toolkit or Ispirer Service. They will be able to work with your new PostgreSQL database.

Tables and data

SQL objects

Built-in functions

Collections

Packages

Tables and data

Tables and data conversion

Ispirer Toolkit converts tables with all related objects. Indexes, referential integrity constraints, and data are migrated to the target PostgreSQL database. All Oracle native data types are converted to the PostgreSQL equivalents.

If necessary, the user can change the default settings of data type mapping.

Functions

Procedures and functions conversion

Oracle user procedures and functions are converted to stored procedures and functions written in PostgreSQL syntax, depending on the version of the target database. Packages are converted to a separate set of objects — procedures and functions.

Package-level

Package-level variables and constants are taken into account

They are migrated to tables that store the actual values, and a set of functions that define and get values of those tables.

Triggers

Triggers conversion

Ispirer Toolkit automatically migrates Oracle triggers to the trigger function, and the trigger itself to the PostgreSQL database. Oracle trigger logic is moved to the trigger function as well. The tool then generates a trigger that calls this trigger function.

Functions and procedures

Built-in functions and procedures conversion

Oracle built-in functions and procedures are converted to their equivalents in PostgreSQL. If there is none, the tool will try to convert the functions to PostgreSQL expressions. They will emulate the same behavior or generate a user-defined function that will work the same way as in the Oracle database.

Methods

Working with collections and their methods

Ispirer Toolkit supports collection conversion of all three types: Associative array, Nested table, Variable-size array (varray). They are converted to a PostgreSQL table. Then a set of user-defined functions is generated. This allows to work with values in such tables.

Methods

Oracle supplied PL/SQL package conversion

Ispirer Toolkit supports conversion of some Supplied PL/SQL Packages, such as UTL_FILE, DBMS_LOB and others. The list can be expanded depending on the requirements of your conversion project.

Migration demo

Check out how Ispirer Toolkit migrates databases efficiently, minimizing the need for manual corrections

Migrate your data without limits!

Need migrations with near-zero downtime and reliable recovery?

Our automated migration service handles everything — without middleware, without altering your source database, and without requiring unique columns.

Try data migration

Pay only for expert hours, no hidden fees

Migration data

Oracle Database to PostgreSQL Migration Challenges and How Ispirer Toolkit Overcomes Them

Aspect Oracle Database PostgreSQL Ispirer
Licensing Enterprise Edition per processor, Standard Edition per processor. Annual support costs Completely free and open source under PostgreSQL License with no licensing fees or usage limitations Provides project-based or time-boxed licenses
Ownership Owned by Oracle Corporation as a proprietary commercial product Open source project maintained by PostgreSQL Global Development Group Ispirer Systems, LLC
SQL Language Uses PL/SQL (Procedural Language/SQL) with robust procedural capabilities and proprietary extensions Uses standard SQL with PL/pgSQL procedural language and supports multiple procedural languages including PL/Python, PL/Perl, and PL/Tcl Converts SQL code to PL/pgSQL automatically, including packages, stored procedures, functions, and triggers; handles Oracle-specific constructs and syntax differences
Basic Data Types Uses NUMBER with precision and scale for numeric data; DATE for dates; XMLTYPE for XML; supports FLOAT as NUMBER subtype, string datatypes Extensive data types including NUMERIC, INTEGER variants, native arrays, JSON, JSONB, UUID, geometric types, and custom user-defined types Provides global and local data type mapping engines; automatically maps Oracle types (NUMBER, DATE, XMLTYPE, etc.) to optimal PostgreSQL equivalents (NUMERIC, TIMESTAMP, XML, etc.) and others
Indexing Options B-tree (default), bitmap indexes for low-cardinality columns, function-based indexes, domain indexes, reverse key indexes B-tree (default), GIN, GiST, BRIN, SP-GiST indexes; supports partial/conditional indexes and specialized indexing for various data types Automatically recreates indexes during migration; translates Oracle index structures to PostgreSQL equivalents; drops unsupported Oracle-specific options

6 undeniable facts to choose conversion with Ispirer

  • Reduced costs

    Reduced costs icon

    Migrating to a more efficient PostgreSQL database can lower operational costs by reducing hardware and software maintenance requirements, optimizing resource utilization, and lowering licensing fees.

  • Modernization & innovation

    Modernization icon

    Migrating to PostgreSQL can enable the adoption of new technologies and features, unlocking new business opportunities and driving innovation. It also creates room for future growth.

  • Added AI precision

    AI icon

    An AI-driven migration toolkit can automate complex tasks, reduce errors, optimize workflows, and accelerate the process, ensuring smoother transitions while minimizing costly system downtime.

  • Enhanced security

    Enhanced security icon

    Newer databases often incorporate advanced security features like encryption, access controls, and threat detection mechanisms, providing better protection against data breaches and cyberattacks.

  • Legacy transformation

    Legacy transformation icon

    Migrating legacy databases to modern systems can upgrade your database, making it easier to maintain, update, and extend in the long run. This creates a more flexible foundation for future growth.

  • No need for documentation

    No documentation icon

    We perform the migration using the source code. There is no need for detailed documentation to begin the migration as there is in development. Our tools analyze the source code and database structure automatically.

They succeeded using Ispirer Toolkit

Achieving 95% automation in PostgreSQL database migration

Oracle, SQL Server → PostgreSQL

Target: PostgreSQL

PostgreSQL database migration -- case card

Project Scope

1 700 000 LoC

Project Duration

12 Months

Industry

Contingent Workforce Management

Sybase ASE to MySQL: 100% automated migration

Sybase ASE → MySQL

Target: MySQL

Sybase ASE to MySQL -- case card

Project Scope

300 000 LoC

Project Duration

12 Months

Industry

Financial Data Utility Provider

Helping HR Software Leader: DB2 OS/390 to SQL Server

DB2 OS/390 → SQL Server

Target: SQL Server

Helping HR Software Leader -- case card

Project Scope

400 000 LoC

Project Duration

3 Months

Industry

Software Developer and Provider

Enhancing Performance: Oracle to Java Migration Automation

Oracle → Java, PostgreSQL

Target: Java, PostgreSQL

Enhancing Performance -- сase card

Project Scope

1 250 000 LoC

Project Duration

14 Months

Industry

Software Developer and Provider

Consulting Firm Cuts Migration Costs by 65% with Ispirer

SQL Server → Java, PostgreSQL

Target: Java, PostgreSQL

Cut Migration Costs -- case card

Project Scope

850 000 LoC

Project Duration

15 Months

Industry

Financial Consulting Firm

Conversion Samples of Oracle to PostgreSQL

Ispirer Toolkit analyzes all object dependencies during the conversion process and provides not only line-by-line conversion, but resolves type conversions as well. The software understands and transforms the necessary inheritance dependencies. It parses the entire source code, builds an internal tree with all the information about the objects, and uses it in the migration process.

The code samples below provide you with more details.

Oracle Collections conversion

  • Oracle

    1. CREATE TYPE employee AS OBJECT (
    2.     id NUMBER,
    3.     Name VARCHAR(300)
    4.     );
    5.   CREATE TYPE employees_tab IS TABLE OF employee;
    6.        
    7.   CREATE OR REPLACE PROCEDURE hire(EMPLOYEES in out employees_tab, id NUMBER, Name VARCHAR) AS
    8.   NEW_EMPLOYEES employees_tab := employees_tab();
    9.   BEGIN
    10.     EMPLOYEES.Extend(1);
    11.     EMPLOYEES(EMPLOYEES.count) := employee(id, Name);
    12.     FOR i IN EMPLOYEES.first..EMPLOYEES.last
    13.     LOOP
    14.       INSERT INTO emp_tab values (EMPLOYEES(i).id, EMPLOYEES(i).Name);
    15.     END LOOP;
    16.     INSERT INTO EMP_TAB SELECT * FROM TABLE(EMPLOYEES);
    17.     NEW_EMPLOYEES.Extend(EMPLOYEES.count);
    18.     NEW_EMPLOYEES.Delete;
    19.   END;

    → PostgreSQL

    1. CREATE TYPE employee AS(id NUMERIC,Name VARCHAR(300));
    2.   -- CREATE TYPE employees_tab IS TABLE OF employee;
    3.  
    4.   CREATE OR REPLACE PROCEDURE hire(INOUT EMPLOYEES employee[] , id NUMERIC, Name VARCHAR)
    5.   LANGUAGE plpgsql
    6.     AS $$
    7.     DECLARE
    8.     NEW_EMPLOYEES  employee[] default array[]:: employee[];
    9.   BEGIN
    10.     EMPLOYEES[coalesce(array_length(EMPLOYEES,1),0)+1] := null;
    11.     EMPLOYEES[coalesce(array_length(EMPLOYEES,1),0)] := row(id,Name);
    12.     FOR i IN array_lower(EMPLOYEES,1) .. array_upper(EMPLOYEES,1)
    13.     LOOP
    14.       INSERT INTO emp_tab  values(EMPLOYEES[i].id, EMPLOYEES[i].Name);
    15.     END LOOP;
    16.     INSERT INTO EMP_TAB  SELECT * FROM UNNEST(EMPLOYEES);
    17.     for i in 1 .. coalesce(array_length(EMPLOYEES,1),0) loop
    18.       NEW_EMPLOYEES[coalesce(array_length(NEW_EMPLOYEES,1),0)+1] := null;
    19.     end loop;
    20.     NEW_EMPLOYEES := array[]:: employee[];
    21.   END; $$;
  • Oracle

    1. CREATE OR REPLACE EDITIONABLE PACKAGE BODY "COMMON_PKG" AS
    2.        
    3.   CUSTOMER_ID NUMBER(10,0);
    4.   TYPE VARCHAR2_AARAY IS TABLE OF VARCHAR2(50) INDEX BY PLS_INTEGER;
    5.   ADDRES_LST VARCHAR2_AARAY;
    6.  
    7.   PROCEDURE PREPARE_CUSTOMER_ADRESSS_BY_ID(CITY_NAME VARCHAR2, CUSTTYPE_ID VARCHAR2)
    8.   IS
    9.   CUR_ADDR VARCHAR2(500);
    10.   CUSTM_ID NUMBER;
    11.     v_int number;
    12.     V_RES  DBMS_UTILITY.lname_array;
    13.   l_clob clob;
    14.   cursor cus_addr(cur_id number) is select address from customer where cust_id =  cur_id or cust_id <5;  
    15.   BEGIN
    16.   l_clob := '';
    17.     select CUST_ID into CUSTM_ID
    18.       from customer
    19.       where CITY = CITY_NAME and CUST_TYPE_CD = CUSTTYPE_ID and ROWNUM <= 1;
    20.   open cus_addr(CUSTM_ID);
    21.   fetch  cus_addr into CUR_ADDR;
    22.   WHILE(cus_addr%found)
    23.   loop
    24.   l_clob := l_clob || CUR_ADDR||',';
    25.   fetch  cus_addr into CUR_ADDR;
    26.   end loop;
    27.   if cus_addr%isopen then
    28.   close cus_addr;
    29.   end if;
    30.   dbms_output.put_line( rtrim(l_clob,',') );
    31.  
    32.   END;  
    33.  
    34.  
    35.   PROCEDURE GET_FIST_NAME_OF_EMPLOYEE_BY_START_DATE(STRT_DATE DATE) is
    36.  
    37.   EMPLOYEE_REC EMPLOYEE%ROWTYPE;
    38.   cursor cur_start_date is select * from EMPLOYEE;  
    39.   BEGIN
    40.     open cur_start_date;
    41.   fetch cur_start_date into EMPLOYEE_REC;
    42.   WHILE(cur_start_date%found)
    43.   loop
    44.   if EMPLOYEE_REC.START_DATE < STRT_DATE THEN
    45.   goto loop_again;
    46.   end if;
    47.   DBMS_OUTPUT.PUT_LINE(EMPLOYEE_REC.FIRST_NAME || '  ' ||EMPLOYEE_REC.LAST_NAME );
    48.   <<loop_again>>
    49.   fetch cur_start_date into EMPLOYEE_REC;
    50.   end loop;
    51.   if cur_start_date%isopen then
    52.   close cur_start_date;
    53.   end if;
    54.   END;  
    55.  
    56.   END COMMON_PKG;

    → PostgreSQL

    1. CREATE SCHEMA  IF NOT EXISTS COMMON_PKG;        
    2.        
    3.   -- TYPE VARCHAR2_AARAY IS TABLE OF VARCHAR2(50) INDEX BY PLS_INTEGER;
    4.  
    5.   DROP TYPE  IF EXISTS COMMON_PKG.GL_VAR_TYPE CASCADE;
    6.   CREATE type COMMON_PKG.GL_VAR_TYPE
    7.   as(CUSTOMER_ID BIGINT,
    8.   ADDRES_LST VARCHAR(50)[]);
    9.   CREATE OR REPLACE FUNCTION COMMON_PKG.INIT_GL_VAR()
    10.   RETURNS VOID LANGUAGE plpgsql
    11.     AS $$
    12.   BEGIN
    13.      
    14.     CREATE TEMPORARY TABLE  COMMON_PKG_GL_VAR AS SELECT(array[]:: VARCHAR(50)[]):: COMMON_PKG.GL_VAR_TYPE AS SWV_GL_VAR_VAL;
    15.     RETURN;
    16.     EXCEPTION
    17.     WHEN SQLSTATE '42P07' THEN
    18.       NULL;
    19.   END; $$;
    20.   CREATE OR REPLACE FUNCTION COMMON_PKG.GET_GL_VAR()
    21.   RETURNS COMMON_PKG.GL_VAR_TYPE LANGUAGE plpgsql
    22.     AS $$
    23.     DECLARE
    24.     SWV_GL_VAR  COMMON_PKG.GL_VAR_TYPE;
    25.   BEGIN
    26.      
    27.     RETURN(select SWV_GL_VAR_VAL:: COMMON_PKG.GL_VAR_TYPE from COMMON_PKG_GL_VAR);
    28.     EXCEPTION
    29.     WHEN OTHERS THEN
    30.       PERFORM COMMON_PKG.INIT_GL_VAR();
    31.       RETURN(select SWV_GL_VAR_VAL:: COMMON_PKG.GL_VAR_TYPE from COMMON_PKG_GL_VAR);
    32.   END; $$;
    33.   CREATE OR REPLACE PROCEDURE COMMON_PKG.SET_GL_VAR(SWP_GLVAR COMMON_PKG.GL_VAR_TYPE)
    34.   LANGUAGE plpgsql
    35.     AS $$
    36.   BEGIN
    37.      
    38.     UPDATE COMMON_PKG_GL_VAR SET SWV_GL_VAR_VAL = SWP_GLVAR;
    39.   END; $$;
    40.   CREATE OR REPLACE PROCEDURE COMMON_PKG.GET_CUSTID_BY_PARAMS(CITY_NAME        VARCHAR,
    41.       CUST_ID_CD        VARCHAR,
    42.       OUT CUST_ID NUMERIC)
    43.   LANGUAGE plpgsql
    44.     AS $$
    45.     DECLARE
    46.     SWV_GL_VAR  COMMON_PKG.GL_VAR_TYPE DEFAULT COMMON_PKG.GET_GL_VAR();
    47.     IN_ID  BIGINT;
    48.   BEGIN
    49.    
    50.     select CUST_ID into STRICT IN_ID
    51.     from CUSTOMER
    52.     where CITY = CITY_NAME and CUST_TYPE_CD = CUST_ID_CD LIMIT 1;
    53.     CUST_ID := IN_ID;
    54.   END; $$;
    55.   CREATE OR REPLACE PROCEDURE COMMON_PKG.PREPARE_CUSTOMER_ADRESSS_BY_ID(CITY_NAME VARCHAR, CUSTTYPE_ID VARCHAR)
    56.   LANGUAGE plpgsql
    57.     AS $$
    58.     DECLARE
    59.     SWV_GL_VAR  COMMON_PKG.GL_VAR_TYPE DEFAULT COMMON_PKG.GET_GL_VAR();
    60.     CUR_ADDR  VARCHAR(500);
    61.     CUSTM_ID  NUMERIC;
    62.     v_int  NUMERIC;
    63.     V_RES  VARCHAR(4000)[] default array[]:: VARCHAR(4000)[];
    64.     l_clob  TEXT;
    65.     CUS_ADDR cursor(cur_id NUMERIC) FOR select ADDRESS from CUSTOMER where cust_id =  cur_id or cust_id < 5;
    66.   BEGIN
    67.    
    68.     l_clob := '';
    69.     select CUST_ID into STRICT CUSTM_ID
    70.     from CUSTOMER
    71.     where CITY = CITY_NAME and CUST_TYPE_CD = CUSTTYPE_ID LIMIT 1;
    72.     open CUS_ADDR(CUSTM_ID);
    73.     fetch  CUS_ADDR into CUR_ADDR;
    74.     WHILE FOUND
    75.     loop
    76.       l_clob := CONCAT(l_clob,CUR_ADDR,',');
    77.       fetch  CUS_ADDR into CUR_ADDR;
    78.     end loop;
    79.     if EXISTS(SELECT 1 FROM pg_cursors WHERE NAME ilike 'CUS_ADDR') then
    80.       close CUS_ADDR;
    81.     end if;
    82.     RAISE NOTICE '%',NULLIF(rtrim(l_clob,','),'');
    83.   END; $$;
    84.   CREATE OR REPLACE PROCEDURE COMMON_PKG.GET_FIST_NAME_OF_EMPLOYEE_BY_START_DATE(STRT_DATE TIMESTAMP)
    85.   LANGUAGE plpgsql
    86.     AS $$
    87.     DECLARE
    88.     SWV_GL_VAR  COMMON_PKG.GL_VAR_TYPE DEFAULT COMMON_PKG.GET_GL_VAR();
    89.     EMPLOYEE_REC  EMPLOYEE%ROWTYPE;
    90.     CUR_START_DATE cursor FOR select * from EMPLOYEE;
    91.   BEGIN
    92.    
    93.     open CUR_START_DATE;
    94.     fetch CUR_START_DATE into EMPLOYEE_REC;
    95.     WHILE FOUND
    96.     loop
    97.       << loop_again >>
    98.       BEGIN
    99.         if EMPLOYEE_REC.START_DATE < STRT_DATE THEN
    100.           EXIT loop_again;
    101.         end if;
    102.         RAISE NOTICE '%',CONCAT(EMPLOYEE_REC.FIRST_NAME,'  ',EMPLOYEE_REC.LAST_NAME);
    103.       END;
    104.       fetch CUR_START_DATE into EMPLOYEE_REC;
    105.     end loop;
    106.     if EXISTS(SELECT 1 FROM pg_cursors WHERE NAME ilike 'CUR_START_DATE') then
    107.         close CUR_START_DATE;
    108.     end if;
    109.   END; $$;
  • Oracle

    1. create or replace Procedure sp_hier_with_cte_and_rownum (configList IN varchar2)
    2.   IS
    3.   refcur sys_refcursor;
    4.   BEGIN
    5.     FOR refcur IN (
    6.       with test as  
    7.       (select configList from dual)
    8.       select regexp_substr(configList, '[^;]+', 1, rownum) config
    9.       from test
    10.       connect by level <= length (regexp_replace(configList, '[^;]+'))  +1
    11.     )
    12.     LOOP
    13.       dbms_output.put_line('config= '||refcur.config);
    14.     END LOOP;
    15.   END;

    → PostgreSQL

    1. create or replace Procedure sp_hier_with_cte_and_rownum(IN configList VARCHAR)
    2.   LANGUAGE plpgsql
    3.   AS $$
    4.   DECLARE
    5.     refcur  REFCURSOR;
    6.     SWV_REFCUR_rec RECORD;
    7.   BEGIN
    8.     FOR SWV_REFCUR_rec IN(
    9.     WITH RECURSIVE
    10.     test as(select configList),
    11.     TabAl_cte AS(SELECT 1 AS LEVEL
    12.     UNION ALL
    13.     SELECT TabAl_cte.LEVEL+1 AS LEVEL        
    14.     FROM TabAl_cte, test
    15.     WHERE(TabAl_cte.LEVEL+1) <= length(regexp_replace(test.configList,'[^;]+','','g'))+1)
    16.     SELECT  SWF_REGEXP_SUBSTR(test.configList,'[^;]+',1,row_number() over()) AS config
    17.     FROM TabAl_cte,test)
    18.     LOOP
    19.       RAISE NOTICE '%',CONCAT('config= ',SWV_REFCUR_rec.config);
    20.     END LOOP;
    21.   END; $$;
  • Oracle

    1. CREATE OR REPLACE PROCEDURE DYNAMIC_DELETE
    2.   AS
    3.   TAB_NAME VARCHAR2(15):='FOR_TYPE';
    4.   TAB_COL VARCHAR2(12):='COL1';
    5.   TAB_COL2 VARCHAR2(12):='COL2';
    6.   COL_VALUE INTEGER:=2000;
    7.   SQL_DELETE VARCHAR2(200);
    8.   BEGIN
    9.   SQL_DELETE:='DELETE '||TAB_NAME||' WHERE ' || TAB_COL2 || '=SYSDATE+5 AND ' ||TAB_COL||' < :value ';
    10.   EXECUTE IMMEDIATE SQL_DELETE USING COL_VALUE;
    11.      
    12.   EXECUTE IMMEDIATE 'begin EXAMPLE_PROC; end;';
    13.   END;

    → PostgreSQL

    1. CREATE OR REPLACE PROCEDURE DYNAMIC_DELETE()
    2.   LANGUAGE plpgsql
    3.     AS $$
    4.     DECLARE
    5.     TAB_NAME  VARCHAR(15) DEFAULT 'FOR_TYPE';
    6.     TAB_COL  VARCHAR(12) DEFAULT 'COL1';        
    7.     TAB_COL2  VARCHAR(12) DEFAULT 'COL2';
    8.     COL_VALUE  INTEGER DEFAULT 2000;
    9.     SQL_DELETE  VARCHAR(200);
    10.   BEGIN
    11.     SQL_DELETE := 'DELETE FROM ' || TAB_NAME || ' WHERE ' || TAB_COL2 || '= LOCALTIMESTAMP+INTERVAL ''5 day'' AND ' || TAB_COL || ' <%1$L ';
    12.     EXECUTE format(SQL_DELETE,COL_VALUE);
    13.          
    14.     EXECUTE  'DO LANGUAGE plpgsql $anonymous_block$ BEGIN    CALL EXAMPLE_PROC(); END; $anonymous_block$';
    15.   END; $$;
  • Oracle

    1. CREATE PROCEDURE         AUTO_TEST (id_value number, text_value varchar2)
    2.   IS
    3.   PRAGMA AUTONOMOUS_TRANSACTION;
    4.   BEGIN
    5.     INSERT INTO AUTONOMOUS_EVENT (id, value)
    6.     VALUES(id_value, text_value);
    7.     COMMIT;
    8.   END AUTO_TEST;

    → PostgreSQL

    1. CREATE EXTENSION IF NOT EXISTS dblink;
    2.      
    3.   --use superuser to run this script
    4.   CREATE SERVER SWL_targetDBname_link FOREIGN DATA WRAPPER dblink_fdw
    5.   OPTIONS (hostaddr '127.0.0.1', dbname 'targetDBname');
    6.  
    7.   CREATE USER MAPPING FOR targetUser SERVER SWL_targetDBname_link
    8.     OPTIONS (user 'targetUser', password 'pass');
    9.            
    10.   GRANT USAGE ON FOREIGN ERVER SWL_targetDBname_link TO targetUser;
    11.      
    12.   -- procedure code
    13.   CREATE OR REPLACE PROCEDURE AUTO_TEST(id_value DOUBLE PRECISION, text_value VARCHAR,IN is_recursive BOOLEAN DEFAULT false)
    14.   LANGUAGE plpgsql
    15.     AS $$
    16.     DECLARE
    17.     v_sql  text;
    18.   BEGIN
    19.     IF   is_recursive = FALSE THEN
    20.       BEGIN
    21.         IF NOT EXISTS(SELECT 1 FROM DBLINK_GET_CONNECTIONS()
    22.         WHERE dblink_get_connections@> '{myconn}') THEN
    23.           PERFORM DBLINK_CONNECT('myconn','SWL_targetDBname_link');
    24.         END IF;
    25.         v_sql := FORMAT('CALL AUTO_TEST( id_value => %L, text_value => %L, is_recursive => TRUE )',id_value,text_value);
    26.            PERFORM DBLINK('myconn',v_sql);
    27.       END;
    28.     ELSE
    29.     --procedure body
    30.       INSERT INTO AUTONOMOUS_EVENT(ID, VALUE)
    31.     VALUES(id_value, text_value);
    32.          
    33.       COMMIT;
    34.     END IF;
    35.   END; $$;
  • Oracle

    1. with demo1 as(
    2.     select XMLType(
    3.     '<hello-world>
    4.     <word seq="1">Hello</word>
    5.     <word seq="2">world</word>
    6.   </hello-world>
    7.   ') XML
    8.   from dual
    9.   )
    10.   select
    11.     t.xml.extract('//word[@seq=1]/text()').getStringVal() col1
    12.     , decode(t.xml.extract('//word[@seq=1]/text()').getStringVal(), 'Hello', 'Hell', 'END') col2
    13.   from demo1 t

    → PostgreSQL

    1. with  demo1 as(select '<hello-world>
    2.     <word seq="1">Hello</word>
    3.     <word seq="2">world</word>
    4.   </hello-world>
    5.   ':: xml AS XML)
    6.   select(trim(replace(xpath('//word[@seq=1]/text()',T.XML):: text,',',''),'{}'):: xml):: text AS COL1
    7.     , CASE(trim(replace(xpath('//word[@seq=1]/text()',T.XML):: text,',',''),'{}'):: xml):: text WHEN 'Hello' THEN 'Hell' ELSE 'END' END AS COL2
    8.   from demo1 T;

Get a free sample code of our Oracle to PostgreSQL conversion

Ispirer Toolkit automatically converts not only a single piece of code, but an entire database. Complex code will require customization of the toolkit

  • Explore how Ispirer Toolkit migrates the source code to the target technology without downloading it.
  • Analyze and compare the source sample with your code to understand which components of your application can be automatically converted using Ispirer Toolkit.
  • Run the database and insert the code to ensure it works properly.
  • Our experts can add new conversion rules within 3-5 business days.
Enter your name.
Enter a valid e-mail address.
Select your country.

Useful articles about database migration

Spectral Core Suite vs Ispirer IDM: Technical Deep Dive for Oracle-to-PostgreSQL Migrations 2026

5 min read

Spectral Core Suite vs Ispirer IDM in 2026: batch full-load with fast code translation, or PostgreSQL-native zero-middleware iterative migration. See which fits.

Oracle GoldenGate 26ai vs Ispirer IDM for Oracle-to-PostgreSQL Migrations (2026 Edition)

6 min read

Compare Oracle GoldenGate 26ai vs Ispirer IDM for Oracle-to-PostgreSQL migrations.

Striim vs Ispirer IDM: Technical Deep Dive for Oracle-to-PostgreSQL Migrations (2026 Edition)

6 min read

Striim vs Ispirer IDM: Technical Deep Dive for Oracle-to-PostgreSQL Migrations (2026 Edition)

Google Cloud Database Migration Service (DMS) vs Ispirer IDM: Technical Deep Dive for Oracle-to-PostgreSQL Migrations 2026

10 min read

Google Cloud DMS vs Ispirer IDM: Which Oracle-to-PostgreSQL tool is best?

Take control of your database migration now

Consult with our expert to better organize for you migration flow.

Frequently Asked Questions

Get answers to the most common questions about database migration.

Want more details?

Request a consultation with our expert

Schedule a call

30 min of constructive conversation

How does the migration tool handle complex Oracle PL/SQL packages and stored procedures?

Ispirer Toolkit parses the full source code of each Oracle package — both specification and body — and builds an internal dependency tree. Package-level variables and constants are migrated to tables with getter/setter functions. Procedures and functions are converted to PL/pgSQL equivalents. Where Oracle constructs have no direct PostgreSQL equivalent, the toolkit generates user-defined functions that replicate the original behavior.

Oracle-specific features like PRAGMA AUTONOMOUS_TRANSACTION, UTL_FILE, and DBMS_LOB are handled through dblink extensions and custom conversion rules.

Ispirer offers InsightWays — a free assessment tool that connects to your Oracle database, analyzes all objects and structures, and produces a complexity and scope report before you commit to migration. The Ispirer Toolkit itself is also available for a free trial with no payment required.

Oracle's licensing model creates a substantial financial burden — per processor, per edition, with annual support costs. PostgreSQL is open source and free to use. Moving from Oracle to PostgreSQL eliminates vendor lock-in, reduces infrastructure costs, opens access to modern extensions without additional cost, and improves cloud readiness across AWS, GCP, and Azure.

Ispirer handles data migration directly — without middleware, without altering the source database, and without requiring unique columns. It supports parallel migration threads, custom data type mapping, BLOB migration at full speed, and Change Data Capture (CDC) for near-zero downtime scenarios.

The recommended approach is a live connection from Ispirer Toolkit to the source Oracle database via ODBC — this gives the tool full visibility into object dependencies and data types. Alternatively, files containing PL/SQL scripts can be converted without a live connection. Ispirer tools read from Oracle in read-only mode with no changes made to the source system.

Not inherently. Performance differences typically arise from configuration and query optimization rather than the database engine itself. Code optimized for Oracle needs to be reviewed and tuned for PostgreSQL after migration — this is a standard step in every Ispirer migration project.

Oracle Corporation does not provide tools or support for migrating to PostgreSQL. Ispirer Toolkit specifically bridges this gap with a 20,000+ rule engine that handles Oracle-specific constructs, data types, and procedural language differences.

Yes. Ispirer Data Migrator supports migration of all Oracle data types, including BLOB, CLOB, RAW, LONG, XMLType, and spatial data. The tool reads from Oracle in read-only mode with no dependency on unique columns or specific table structures.

Ora2Pg is a free open-source Oracle to Postgres migration tool that handles basic schema migration and data export. It requires significant manual effort for complex PL/SQL, Oracle packages, hierarchical queries, and dynamic SQL. For large-scale or complex migrations, automated tools like Ispirer Toolkit offer significantly higher automation rates and dedicated expert support.

Automation rates depend heavily on code complexity. For straightforward schema and simple stored procedures, automation routinely exceeds 90%. For codebases heavy in Oracle-specific features, rates vary and are assessed during pre-migration analysis. Ispirer's InsightWays tool provides a complexity index per object so you can estimate manual effort before the project begins. Customization of the toolkit can further increase automation — up to 95% as demonstrated in the Magnit Global project.

Ispirer Toolkit includes both global and local data type mapping engines. Oracle NUMBER maps to NUMERIC, VARCHAR2 to VARCHAR, DATE to TIMESTAMP, XMLTYPE to XML, RAW to BYTEA. Users can override default mappings at the object or column level where project requirements differ.

Does the automated solution support the migration of partitioned tables and advanced indexing?

Yes. Ispirer Toolkit migrates partitioned tables, translating Oracle's partitioning syntax to PostgreSQL's native declarative partitioning. Oracle index types are translated to their PostgreSQL equivalents — B-tree, GIN, GiST, BRIN, partial indexes. Oracle-specific index options with no PostgreSQL equivalent are dropped with logged warnings.

Ispirer converts Oracle global temporary tables to PostgreSQL temporary tables using ON COMMIT DELETE ROWS or ON COMMIT PRESERVE ROWS behavior depending on the Oracle table's configuration, and adjusts any code that references them accordingly.

Yes. Oracle CONNECT BY hierarchical queries are converted to PostgreSQL WITH RECURSIVE CTEs. The toolkit handles CONNECT BY LEVEL, CONNECT BY PRIOR, START WITH, and NOCYCLE clauses. A direct before/after example is available in the code samples section above.

Ispirer performs data integrity testing using snapshots of the source database. Migrated data in PostgreSQL is compared against source Oracle data using automated checks and scenario-based testing derived from the source application's actual usage patterns. Discrepancies are logged, analyzed, and corrected before production cutover.

Yes. Ispirer uses Change Data Capture (CDC) to replicate ongoing data changes from Oracle to PostgreSQL while the source remains live. Preliminary cold-data migration is performed in advance for large datasets, reducing the final cutover window significantly. The 12 TB in 12 hours case study above demonstrates this approach in production.

Oracle sequences are migrated to PostgreSQL sequences with matching start values and increment settings. Triggers are converted to PostgreSQL trigger functions plus a trigger definition that calls the function. Views are converted directly to PostgreSQL view syntax. All three object types are included in the full automated migration run.

The main areas to address are query plan differences, index strategy, connection pooling, VACUUM and autovacuum configuration for write-heavy tables, and partitioning design. Ispirer's post-migration optimization step addresses these systematically.

The toolkit parses each Oracle object's source code, builds a full syntax tree including type information and inter-object dependencies, and applies its rule engine (20,000+ rules) to produce PL/pgSQL output. It handles data type resolution, cursor behavior, exception handling, GOTO statement transformation, and built-in function substitution.

Ispirer Toolkit converts: tables and all constraints, indexes, views, sequences, functions, stored procedures, packages (specification and body), triggers, collection types (associative arrays, nested tables, varrays), object types, and Oracle supplied packages (UTL_FILE, DBMS_LOB, and others). Dynamic SQL, hierarchical queries, spatial functions, XML functions, and PRAGMA AUTONOMOUS_TRANSACTION are also handled.

The Free Trial is available at no cost with no payment required. Contact Ispirer to discuss trial scope — the team will help you configure the toolkit for your environment and run a test migration on a representative portion of your codebase.

Yes. RAW maps to BYTEA, LONG to TEXT. BFILE requires a custom approach since PostgreSQL has no native equivalent — Ispirer handles this via configuration options depending on how BFILE is used in the source code.

Yes. The free InsightWays assessment tool generates a detailed report including object counts, complexity indexes per object, and estimated automation rates. A test migration of representative code further validates these estimates against actual output.

Oracle CONNECT BY queries are rewritten as WITH RECURSIVE CTEs in PostgreSQL. The toolkit maps CONNECT BY LEVEL to recursive iteration depth, CONNECT BY PRIOR to the recursive join condition, START WITH to the base case of the CTE, and NOCYCLE to cycle detection logic.

Yes. Ispirer provides expert support during the trial to help with toolkit configuration and initial test migration. If conversion rules need to be added for your specific codebase, the engineering team can implement new rules within 3–5 business days.

Data integrity is maintained through read-only source access, row count comparison, and scenario-based testing using source application test cases. For numeric precision, type mapping preserves Oracle NUMBER precision in PostgreSQL NUMERIC equivalents. Ispirer runs a full data integrity testing phase before sign-off.

Yes. Ispirer Toolkit has 300+ configuration parameters for SQL objects and data migration behavior. Users can define custom data type mappings, adjust how specific Oracle constructs are handled, and work with Ispirer engineers to add entirely new conversion rules.

Contact Ispirer for current system requirements — they vary based on database size, whether you're running schema conversion only or full data migration, and your target environment.

Yes, the migration follows a repeatable sequence. Start with an assessment of schemas, object counts, PL/SQL volume and external dependencies. One of the few free options on the market for this stage is InsightWays by Ispirer, which runs offline with read-only access and returns object and line of code counts together with flagged issues.

Second, convert the schema with explicit type decisions. NUMBER with scale zero becomes smallint, integer or bigint by range, NUMBER with a scale becomes numeric, NUMBER without precision becomes numeric or double precision depending on real usage, DATE becomes timestamp(0) because Oracle stores a time component, VARCHAR2 becomes varchar, CLOB becomes text, BLOB and RAW become bytea.

Third, convert PL/SQL to PL/pgSQL and packages to schemas. Fourth, transfer the data and reset sequences to current maximum values. Fifth, run functional and performance testing. Sixth, plan the cutover window.

The semantic risk that runs through all six steps is that Oracle stores an empty string as NULL while PostgreSQL does not, which changes IS NULL checks, constraint behavior and concatenation results.

Yes, and they differ in scope. One of the tools that stands out on the market is SQLWays by Ispirer, which converts schema objects, stored procedures, triggers, functions and views together with the data, reports automation of up to 95 percent on supported paths, and can be extended with custom rules for company specific code, which is what raises the rate on large systems. Ora2Pg is a free option covering schema and part of PL/SQL, while pgloader moves data only.

While all auto-generated code requires testing, the actual effort involved hinges on your tool’s quality. Extra attention should go to features that most often require manual intervention: autonomous transactions, DBMS_ package calls, CONNECT BY hierarchies, dynamic SQL built at runtime, optimizer hints and logic that depends on Oracle treating an empty string as NULL.

For large volumes and short maintenance windows, Ispirer Data Migrator moves data with change data capture that does not require access to REDO logs, so the source stays read only during the transfer.

Plan the schedule around testing rather than around code conversion, since that is where the remaining risk lies.