Migrate Oracle SERIALLY_REUSABLE Pragma packages into Amazon Aurora or Amazon RDS for PostgreSQL
Vinay Paladi, Amazon Web Services
Summary
This pattern provides a step-by-step approach for migrating Oracle packages that use the SERIALLY_REUSABLE Pragma to Amazon Aurora PostgreSQL-Compatible Edition or Amazon RDS for PostgreSQL on AWS, while maintaining the original functionality.
The PRAGMA SERIALLY_REUSABLE indicates that the package state is needed only for the duration of one call to the server (for example, a PL/SQL anonymous block or a stored procedure call through a database link). After this call, the storage for the package variables can be reused, reducing memory consumption.
PostgreSQL doesn't natively support the concept of SERIALLY_REUSABLE Pragma. To achieve equivalent functionality, this pattern uses a wrapper function approach combined with the AWS Database Migration Service (AWS DMS) Schema Conversion (AWS DMS SC) feature to migrate the package structure. The example script provided demonstrates how to preserve the reset-on-each-call behavior in PostgreSQL.
For more information, see SERIALLY_REUSABLE
Prerequisites and limitations
An active AWS account
Access to the AWS DMS Schema Conversion service
An Amazon Aurora PostgreSQL-Compatible Edition database or an Amazon RDS for PostgreSQL database
Oracle database version 10g or later
Architecture
Source technology stack
On-premises Oracle database
Target technology stack
Aurora PostgreSQL-Compatible
or Amazon RDS for PostgreSQL AWS DMS Schema Conversion
Migration architecture

Tools
AWS services
AWS Database Migration Service (AWS DMS) Schema Conversion makes database migrations between different types of databases more predictable. Use it to assess the complexity of your migration for your source data provider and to convert database schemas and code objects. You can then apply the converted code to your target database.
Amazon Aurora PostgreSQL-Compatible Edition is a fully managed, ACID-compliant relational database engine that helps you set up, operate, and scale PostgreSQL deployments.
Amazon Relational Database Service (Amazon RDS) for PostgreSQL helps you set up, operate, and scale a PostgreSQL relational database in the AWS Cloud.
Other tools
pgAdmin
is an open-source management tool for PostgreSQL. It provides a graphical interface that helps you create, maintain, and use database objects.
Best practices
Always use
reset_vars = 1for top-level calls andreset_vars = 0for internal sub-calls.Keep all default values in the
$initfunction as a single source of truth.Match Oracle variable names in PostgreSQL for traceability.
Validate by comparing Oracle
DBMS_OUTPUTwith PostgreSQLRAISE NOTICEoutput.Test in separate PostgreSQL sessions to confirm variables reset between calls.
Epics
| Task | Description | Skills required |
|---|---|---|
Set up AWS DMS SC. | Configure AWS DMS connectivity to the source database. For more information, see Converting database schemas using DMS Schema Conversion. | DBA, Developer |
Convert the script. | Use AWS DMS SC to convert the Oracle package by selecting the target database as Aurora PostgreSQL-Compatible. | DBA, Developer |
Save the .sql files. | Before you save the .sql file, modify the Project Settings option in AWS DMS SC to Single file per stage. This configures AWS DMS to separate the .sql file into multiple .sql files based on object type. | DBA, Developer |
Change the code. | Open the | DBA, Developer |
Test the conversion. | Deploy the | DBA, Developer |
Troubleshooting
| Issue | Solution |
|---|---|
Field does not exist error when accessing package variables. | Ensure that the |
Variables not resetting between top-level calls or resetting unexpectedly during internal sub-calls. | Use |
Related resources
Additional information
-------Source Oracle Code: CREATE OR REPLACE PACKAGE test_pkg_var IS PRAGMA SERIALLY_REUSABLE; PROCEDURE function_1(test_id NUMBER); PROCEDURE function_2(test_id NUMBER); END; / CREATE OR REPLACE PACKAGE BODY test_pkg_var IS PRAGMA SERIALLY_REUSABLE; v_char VARCHAR2(20) := 'DEFAULT_VALUE'; v_num NUMBER := 123; PROCEDURE function_2(test_id NUMBER) IS BEGIN dbms_output.put_line('function_2 => v_char=' || v_char || ', v_num=' || v_num); END; PROCEDURE function_1(test_id NUMBER) IS BEGIN dbms_output.put_line('function_1 => v_char=' || v_char || ', v_num=' || v_num); v_char := 'MODIFIED_VALUE'; dbms_output.put_line('function_1 => v_char after update=' || v_char); function_2(0); END; END test_pkg_var; / SET SERVEROUTPUT ON EXEC test_pkg_var.function_1(1); EXEC test_pkg_var.function_2(1); ------Target PostgreSQL Code: CREATE SCHEMA IF NOT EXISTS testoracle; CREATE OR REPLACE FUNCTION testoracle.test_pkg_var$init(reset_vars IN INTEGER DEFAULT 0) RETURNS void AS $BODY$ DECLARE v_need_init BOOLEAN; BEGIN v_need_init := aws_oracle_ext.packageinitialize(proutinename => 'testoracle.test_pkg_var'); IF v_need_init OR reset_vars = 1 THEN PERFORM aws_oracle_ext.setglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_char', pval => 'DEFAULT_VALUE'::CHARACTER VARYING(20)); PERFORM aws_oracle_ext.setglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_num', pval => 123); END IF; END; $BODY$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE testoracle.test_pkg_var$function_1(reset_vars INT DEFAULT 1) AS $BODY$ BEGIN PERFORM testoracle.test_pkg_var$init(reset_vars); RAISE NOTICE 'function_1 => v_char=%, v_num=%', aws_oracle_ext.getglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_char', ptp => NULL::CHARACTER VARYING(20)), aws_oracle_ext.getglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_num', ptp => NULL::DOUBLE PRECISION); PERFORM aws_oracle_ext.setglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_char', pval => 'MODIFIED_VALUE'::CHARACTER VARYING(20)); RAISE NOTICE 'function_1 => v_char after update=%', aws_oracle_ext.getglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_char', ptp => NULL::CHARACTER VARYING(20)); CALL testoracle.test_pkg_var$function_2(0); END; $BODY$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE testoracle.test_pkg_var$function_2(reset_vars INT DEFAULT 1) AS $BODY$ BEGIN PERFORM testoracle.test_pkg_var$init(reset_vars); RAISE NOTICE 'function_2 => v_char=%, v_num=%', aws_oracle_ext.getglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_char', ptp => NULL::CHARACTER VARYING(20)), aws_oracle_ext.getglobalvariable(proutinename => 'testoracle.test_pkg_var', pvariable => 'v_num', ptp => NULL::DOUBLE PRECISION); END; $BODY$ LANGUAGE plpgsql; CALL testoracle.test_pkg_var$function_1(1); -- loads defaults, sets v_char='MODIFIED_VALUE', function_2 sees 'MODIFIED_VALUE' CALL testoracle.test_pkg_var$function_2(1); -- new transcation: PRAGMA reset, sees 'DEFAULT_VALUE'