Управление типами столбцов

PG_NUMERIC_TYPE

Если задано значение 1, переносимые числовые типы заменяются внутренними типами Postgres Pro. Тип данных Oracle NUMBER(p,s) преобразовывается в типы данных Postgres Pro real и float приблизительно. Если есть поля с денежными суммами, во избежание проблем с округлением десятичных чисел необходимо сохранить тот же тип Postgres Pro numeric(p,s). Задавайте эту директиву, только если точность обязательна, поскольку преобразование в numeric(p,s) выполняется медленнее, чем в real или double precision .

PG_INTEGER_TYPE

Если задано значение 1, переносимые числовые типы заменяются внутренними типами Postgres Pro. Типы данных Oracle NUMBER(p) и NUMBER преобразуются в типы данных Postgres Pro smallint, integer или bigint в зависимости от точности. NUMBER без указания точности преобразуется в DEFAULT_NUMERIC (см. ниже).

DEFAULT_NUMERIC

NUMBER без указания точности преобразуется по умолчанию в bigint, только если PG_INTEGER_TYPE имеет значение true. Можно поменять значение переменной на любой тип Postgres Pro, такой как integer или float.

DATA_TYPE

Если при преобразовании типов вы столкнулись с проблемами, используйте эту директиву, чтобы переопределить соответствие типов Oracle и Postgres Pro для преобразования ora2pgpro. Через запятую указываются пары типов тип Oracle:тип Postgres Pro. По умолчанию используется такой список:

DATA_TYPE       VARCHAR2:varchar,NVARCHAR2:varchar,NVARCHAR:varchar,NCHAR:char,DATE:timestamp(0),LONG:text,LONG RAW:bytea,CLOB:text,NCLOB:text,BLOB:bytea,BFILE:bytea,RAW(16):uuid,RAW(32):uuid,RAW:bytea,UROWID:oid,ROWID:oid,FLOAT:double precision,DEC:decimal,DECIMAL:decimal,DOUBLE PRECISION:double precision,INT:integer,INTEGER:integer,REAL:real,SMALLINT:smallint,BINARY_FLOAT:double precision,BINARY_DOUBLE:double precision,TIMESTAMP:timestamp,XMLTYPE:xml,BINARY_INTEGER:integer,PLS_INTEGER:integer,TIMESTAMP WITH TIME ZONE:timestamp with time zone,TIMESTAMP WITH LOCAL TIME ZONE:timestamp with time zone

Имя директивы и определяемый список должны записываться в одной строке.

Обратите внимание, что если обнаруживаются столбцы типа RAW(16) и RAW(32) или в столбце типа RAW стоит значение по умолчанию SYS_GUID(), ora2pgpro автоматически преобразует тип столбца в uuid, что правильно в большинстве случаев. Такие данные автоматически переносятся как данные типа Postgres Pro uuid, предоставляемого модулем uuid-ossp.

Для замены типа с указанием точности и масштаба необходимо экранировать запятую с помощью символа обратной косой черты. Например, для преобразования всех значений типа NUMBER(*,0) в bigint вместо numeric(38), запишите так:

DATA_TYPE       NUMBER(*\,0):bigint

Записывайте только тот тип, который необходимо переопределить, не следует копировать все значения преобразования по умолчанию.

Преобразование BFILE имеет ряд особенностей. Если указать целевой тип TEXT, значения будут содержать только полный путь к внешнему файлу. Если указать BYTEA (по умолчанию), ora2pgpro экспортирует содержимое BFILE как bytea. Если указать целевой тип EFILE, ora2pgpro экспортирует данные как записи EFILE: (DIRECTORY, FILENAME). Используйте тип экспорта DIRECTORY, чтобы извлечь каталоги и права для этих каталогов.

SQL-функции для получения пути к BFILE нет, ora2pgpro создаёт её с использованием пакета DBMS_LOB.

CREATE OR REPLACE FUNCTION ora2pg_get_bfilename( p_bfile IN BFILE )
RETURN VARCHAR2
AS
    l_dir   VARCHAR2(4000);
    l_fname VARCHAR2(4000);
    l_path  VARCHAR2(4000);
BEGIN
    dbms_lob.FILEGETNAME( p_bfile, l_dir, l_fname );
    SELECT directory_path INTO l_path FROM all_directories
        WHERE directory_name = l_dir;
    l_dir := rtrim(l_path,'/');
    RETURN l_dir || '/' || l_fname;
END;

Эта функция создаётся, только если ora2pgpro находит таблицу со столбцом типа BFILE и указан целевой тип TEXT. По окончании экспорта функция удаляется. Директива используется с типами экспорта COPY и INSERT.

SQL-функции для получения записи типа EFILE из BFILE нет, ora2pgpro создаёт её с использованием пакета DBMS_LOB.

CREATE OR REPLACE FUNCTION ora2pg_get_efile( p_bfile IN BFILE )
RETURN VARCHAR2
AS
    l_dir   VARCHAR2(4000);
    l_fname VARCHAR2(4000);
BEGIN
    dbms_lob.FILEGETNAME( p_bfile, l_dir, l_fname );
    RETURN '(' || l_dir || ',' || l_fnamei || ')';
END;

Эта функция создаётся, только если ora2pgpro находит таблицу со столбцом типа BFILE и указан целевой тип EFILE. По окончании экспорта функция удаляется. Директива используется с типами экспорта COPY и INSERT.

Чтобы указать целевой тип, используйте директиву DATA_TYPE.

DATA_TYPE       BFILE:EFILE

Тип EFILE — это пользовательский тип, который можно создать с помощью расширения external_file для портирования типа BFILE в Postgres Pro.

SQL-функции для получения содержимого BFILE нет, ora2pgpro создаёт её с использованием пакета DBMS_LOB.

CREATE OR REPLACE FUNCTION ora2pg_get_bfile( p_bfile IN BFILE ) RETURN
BLOB
  AS
        filecontent BLOB := NULL;
        src_file BFILE := NULL;
        l_step PLS_INTEGER := 12000;
        l_dir   VARCHAR2(4000);
        l_fname VARCHAR2(4000);
        offset NUMBER := 1;
  BEGIN
    IF p_bfile IS NULL THEN
      RETURN NULL;
    END IF;

DBMS_LOB.FILEGETNAME( p_bfile, l_dir, l_fname );
src_file := BFILENAME( l_dir, l_fname );
IF src_file IS NULL THEN
    RETURN NULL;
END IF;

    DBMS_LOB.FILEOPEN(src_file, DBMS_LOB.FILE_READONLY);
    DBMS_LOB.CREATETEMPORARY(filecontent, true);
    DBMS_LOB.LOADBLOBFROMFILE (filecontent, src_file, DBMS_LOB.LOBMAXSIZE, offset, offset);
    DBMS_LOB.FILECLOSE(src_file);
    RETURN filecontent;
END;

Эта функция создаётся, только если ora2pgpro находит таблицу со столбцом типа BFILE и указан целевой тип bytea (по умолчанию). По окончании экспорта функция удаляется. Директива используется с типами экспорта COPY и INSERT.

Типы ROWID и UROWID преобразуются в OID по умолчанию, но при импорте данных будут выдаваться ошибки. Аналогичного типа данных нет, поэтому используйте директиву DATA_TYPE, чтобы указать соответствующий тип Postgres Pro. Можно рассмотреть возможность замены на bigserial (последовательность с автоувеличением), text или uuid.

MODIFY_TYPE

Иногда может потребоваться принудительно использовать определённый целевой тип: например, столбец, экспортируемый ora2pgpro с типом timestamp, можно принудительно экспортировать как date. Значение следует указывать в формате TABLE:COLUMN:TYPE через запятую. Если внутри определения типа нужна запятая или пробел, следует экранировать их с помощью символа обратной косой черты.

MODIFY_TYPE     TABLE1:COL3:varchar,TABLE1:COL4:decimal(9\,6)

Тип table1.col3 заменяется на varchar, а table1.col4 — на decimal с указанием точности и масштаба.

Если задан пользовательский тип столбца, ora2pgpro автоматически определяет составной тип и экспортирует данные с помощью функции ROW(). Некоторые пользовательские типы Oracle представляют собой массивы из значений встроенных типов, в этом случае можно преобразовать значения такого типа в простой массив из значений встроенных типов Postgres Pro. Для этого укажите необходимый целевой тип, и ora2pgpro преобразует данные в массив. Например, если есть такое определение в Oracle:

CREATE OR REPLACE TYPE mem_type IS VARRAY(10) of VARCHAR2(15);
CREATE TABLE club (Name VARCHAR2(10),
        Address VARCHAR2(20),
        City VARCHAR2(20),
        Phone VARCHAR2(8),
        Members mem_type
);

Здесь пользовательский тип mem_type — это простой массив строк, который можно преобразовать следующим образом:

CREATE TABLE club (
        name varchar(10),
        address varchar(20),
        city varchar(20),
        phone varchar(8),
        members text[]
) ;

Директиву следует указывать следующим образом:

MODIFY_TYPE     CLUB:MEMBERS:text[]

ora2pgpro преобразует все данные из этого столбца в нужный формат. Поддерживаются массивы значений только символьных и числовых типов.

TO_NUMBER_CONVERSION

По умолчанию вызовы функции TO_NUMBER в Oracle преобразовываются в функции приведения к типу numeric. Например, TO_NUMBER('10.1234') преобразуется в вызов to_number('10.1234')::numeric в Postgres Pro. Измените значение этой директивы, если требуется выполнять приведение к типу integer или bigint. Формат приведения к типу тоже можно указать в значении директивы: например, со значением TO_NUMBER_CONVERSION 99999999999999999999.9999999999 код выше будет преобразован в TO_NUMBER('10.1234', '99999999999999999999.9999999999'). Любое значение директивы, отличное от numeric, integer или bigint, принимается как маска формата. Если значение отсутствует, преобразование не выполняется.

VARCHAR_TO_TEXT

По умолчанию varchar2 без ограничения размера преобразуется в text. Если необходимо сохранить varchar, отключите эту директиву.

FORCE_IDENTITY_BIGINT

Как правило, столбец идентификации должен иметь тип bigint, чтобы соответствовать последовательности с автоувеличением, поэтому ora2pgpro всегда принудительно использует bigint. Если по каким-либо причинам необходимо сохранить тип данных, заданный для столбца идентификации, отключите эту директиву.

TO_CHAR_NOTIMEZONE

Включите эту директиву, если необходимо удалять информацию о часовом поясе для функций TO_CHAR(). По умолчанию отключена.