L.2. Экспорт пакетов с использованием ora2pgpro #
ora2pgpro — это утилита, основанная на приложении ora2pg, которая может использоваться для портирования пакетов и автономных транзакций Oracle в пакеты и автономные транзакции Postgres Pro при переносе базы данных из Oracle в схему, совместимую с Postgres Pro. Утилита ora2pgpro правильно извлекает объявления типов и переменных из тела пакета и спецификации, включая секцию инициализации. Кроме того, ora2pgpro экспортирует автономные транзакции напрямую, в отличие от приложения ora2pg, которое преобразовывает автономные транзакции в функции-обёртки, используя dblink или pg_background. Стоит отметить, что автономные транзакции в Oracle и Postgres Pro синтаксически сильно различаются. На данный момент циклические зависимости пакетов не поддерживаются.
Чтобы экспортировать пакеты, используя ora2pgpro, сначала отредактируйте файл ora2pgpro.conf.
- Настройте параметры для управления доступом к базе данных Oracle. - ORACLE_HOME - "домашний_каталог_oracle"ORACLE_DSN dbi:Oracle:host=localhost;sid=- SID;port=1521 ORACLE_USER- ПОЛЬЗОВАТЕЛЬORACLE_PWD- ПАРОЛЬSCHEMA- СХЕМА
- Вы можете установить для переменной - TYPEзначение- PACKAGE. Обратите внимание, что вы также можете установить тип экспорта при запуске ora2pgpro, как показано в примере ниже.
- Если вы хотите экспортировать автономные транзакции напрямую как автономные транзакции Postgres Pro Enterprise, установите для параметра - POSTGRESPRO_ATXзначение 1. Обратите внимание, что при этом отключается параметр- AUTONOMOUS_TRANSACTION, отвечающий за преобразование автономных транзакций в функции-обёртки.- POSTGRESPRO_ATX 1 
- Если вы хотите экспортировать только некоторые пакеты, перечислите их через запятую в параметре - INCLUDE_PACKAGESили укажите имена ненужных пакетов в параметре- EXCLUDE_PACKAGES.- INCLUDE_PACKAGES 'PKG_A', 'PKG_B' 
Теперь можно запустить ora2pgpro.
ora2pgpro -t PACKAGE -c ora2pgpro.conf -o packages.sql
В приведённом ниже простом примере показано, как можно перенести пакет CUSTOMER_PKG, используя ora2pgpro. Так выглядит версия Oracle:
CREATE OR REPLACE PACKAGE customer_pkg IS
  gBatchSize constant integer := 100;
  type
    TCustomerInfo is record
    (
      Id          number(9,0),
      Name        varchar2(32 char),
      Description varchar2(512 char)
    );
  type
    TBuffer is table of TCustomerInfo index by pls_integer;
  v_gBuffer TBuffer;
  v_cMainCustomer constant number(9,0) := 1;
  v_gCurrentCustomerId number(9,0);
...
  PROCEDURE dump(v_pCustomer in out nocopy TCustomerInfo);
  PROCEDURE init_package;
END;
CREATE OR REPLACE PACKAGE BODY customer_pkg IS
...
  PROCEDURE dump(v_pCustomer in out nocopy TCustomerInfo) IS
  BEGIN
    console.log('------------------  Dump of customer_pkg.TCustomerInfo  ------------------------');
    console.log('Id          => ' || v_pCustomer.Id);
    console.log('Name        => ' || v_pCustomer.Name);
    console.log('Description => ' || v_pCustomer.Description);
    console.log('--------------------------------------------------------------------------------');
  END;
  PROCEDURE init_package IS
  BEGIN
    v_gCurrentCustomerId := 0;
  END;
BEGIN
  init_package();
END;А так будет выглядеть этот пакет в Postgres Pro:
-- Oracle package 'CUSTOMER_PKG' declaration, edit to match PostgreSQL syntax
DROP SCHEMA IF EXISTS customer_pkg CASCADE;
CREATE SCHEMA IF NOT EXISTS customer_pkg;
CREATE TYPE customer_pkg.tcustomerinfo AS (
Id          integer,
      Name        varchar(32),
      Description varchar(512)
);
CREATE TYPE customer_pkg.tbuffer AS (tbuffer CUSTOMER_PKG.TCustomerInfo[]);
CREATE OR REPLACE FUNCTION customer_pkg.__init__ () RETURNS VOID AS $body$
#import CONSOLE
DECLARE
	gBatchSize constant integer := 100;
	v_gBuffer CUSTOMER_PKG.TBuffer;
	v_cMainCustomer constant integer := 1;
	v_gCurrentCustomerId integer;
BEGIN
  CALL customer_pkg.init_package();
end;
$body$
LANGUAGE PLPGSQL
SECURITY DEFINER
;
-- REVOKE ALL ON FUNCTION customer_pkg.__init__ () FROM PUBLIC;
CREATE OR REPLACE PROCEDURE customer_pkg.init_package () AS $body$
#package
BEGIN
    v_gCurrentCustomerId := 0;
  end;
$body$
LANGUAGE PLPGSQL
SECURITY DEFINER
;
-- REVOKE ALL ON PROCEDURE customer_pkg.init_package () FROM PUBLIC;
CREATE OR REPLACE PROCEDURE customer_pkg.dump (v_pCustomer INOUT CUSTOMER_PKG.TCustomerInfo) AS $body$
#package
BEGIN
    CALL console.log('------------------  Dump of customer_pkg.TCustomerInfo  ------------------------');
    CALL console.log('Id          => ' || v_pCustomer.Id);
    CALL console.log('Name        => ' || v_pCustomer.Name);
    CALL console.log('Description => ' || v_pCustomer.Description);
    CALL console.log('--------------------------------------------------------------------------------');
  end;
$body$
LANGUAGE PLPGSQL
SECURITY DEFINER
;
-- REVOKE ALL ON PROCEDURE customer_pkg.dump (v_pCustomer INOUT CUSTOMER_PKG.TCustomerInfo) FROM PUBLIC;Полные примеры пакетов доступны на ora2pgpro.postgrespro.ru. Скрипты распространяются по лицензии PostgreSQL. См. также документацию ora2pgpro.