Конвертация BULK COLLECT в PostgreSQL
BULK COLLECT — это метод получения данных, во время которого в коллекцию одновременно помещается множество строк. Проблематичной может стать конвертация процедур из баз данных, поддерживающих этот процесс, например, Oracle, в системы, которые его не поддерживают, например, PostgreSQL. Инструмент Конвертум может решить эту проблему и преобразовать процедуры, содержащие BULK COLLECT, несколькими способами. Рассмотрим на примере ковнвертации процедур из Oracle в PostgreSQL.
Инструмент Конвертум преобразует переменные типа collection либо во временные таблицы, либо в массив. Это зависит от параметра TABLE_TYPE_CONVERSION в разделе [POSTGRE] ini-файла (как установить параметры в Конвертум Мастере):
TABLE_TYPE_CONVERSION может иметь следующие значения:
- TABLE_TYPE_CONVERSION=Tables
- TABLE_TYPE_CONVERSION=Arrays
По умолчанию используется значение "Arrays". Оно используется, когда параметр отсутствует. Если установлено значение "Arrays", то переменные типа collection преобразуются в массивы, в противном случае — во временные таблицы. Конвертация таких переменных в массивы удобнее для дальнейшей работы с ними. Подробнее об этом читайте в статье "Конвертация табличных типов с помощью массивов".
В случае, когда переменная типа коллекция становится временной таблицей, BULK COLLECT преобразуется в простую вставку в созданную таблицу.
Код Oracle:
CREATE TYPE type_bulk AS object (p1 integer, p2 varchar2(22));
CREATE TYPE type_bulk_tab AS TABLE OF type_bulk;
CREATE FUNCTION func_for_bulk(par IN NUMBER)
RETURN type_bulk_tab AS RESULTS type_bulk_tab;
BEGIN
SELECT type_bulk(p1,p2)
BULK COLLECT INTO RESULTS
FROM (SELECT c1 as p1, c2 as p2 from table_for_bulk);
RETURN RESULTS;
END;
После преобразования с помощью нашего инструмента мы получим следующий результат в PostgreSQL:
CREATE FUNCTION FUNC_FOR_BULK (IN PAR DOUBLE PRECISION)
RETURNS TABLE ( SWC_Index INTEGER, p1 INTEGER, p2 VARCHAR(22) )
LANGUAGE plpgsql AS $$
BEGIN
create temporary table if not exists SWT_FUNC_FOR_BULK_RESULTS ( SWC_INDEX INTEGER NOT NULL, P1 INTEGER, P2
VARCHAR(22) );
DELETE FROM SWT_FUNC_FOR_BULK_RESULTS;
INSERT INTO SWT_FUNC_FOR_BULK_RESULTS SELECT row_number() OVER(), TabAl.P1,TabAl.P2 from(SELECT C1 as P1,C2
as P2 from TABLE_FOR_BULK) AS TABAL;
RETURN QUERY(SELECT SWT_FUNC_FOR_BULK_RESULTS.SWC_INDEX, SWT_FUNC_FOR_BULK_RESULTS.P1,
SWT_FUNC_FOR_BULK_RESULTS.P2 FROM SWT_FUNC_FOR_BULK_RESULTS);
END; $$;
Если для BULK COLLECTION данных используется несколько переменных, для каждой из них создаются временные таблицы.
Код Oracle:
SELECT id, full_name
BULK COLLECT INTO v_id, v_full_name
FROM TABLE_FOR_BULK;
Код PostgreSQL:
create temporary table if not exists SWT_PRC_BULK_COLLECT_V_FULL_NAME ( SWC_Index INTEGER NOT NULL, SWC_Value
VARCHAR(30) );
DELETE FROM SWT_PRC_BULK_COLLECT_V_FULL_NAME;
create temporary table if not exists SWT_PRC_BULK_COLLECT_V_ID ( SWC_Index INTEGER NOT NULL, SWC_Value DOUBLE
PRECISION );
DELETE FROM SWT_PRC_BULK_COLLECT_V_ID;
INSERT INTO SWT_PRC_BULK_COLLECT_V_ID SELECT row_number() OVER(), id FROM TABLE_FOR_BULK;
INSERT INTO SWT_PRC_BULK_COLLECT_V_FULL_NAME SELECT row_number() OVER(), full_name FROM TABLE_FOR_BULK;
Если переменная типа varray_type преобразуется в массив с помощью опции TABLE_TYPE_CONVERSION=Arrays, вместо BULK COLLECTION создается новый массив, который затем присваивается переменной типа array. Код Oracle:
CREATE FUNCTION func_with_varray()
RETURN varray_type IS
Arr varray_type := varray_type();
BEGIN
SELECT name
BULK COLLECT INTO Arr
FROM TABLE_FOR_BULK;
RETURN Arr;
END;
Код PostgreSQL:
CREATE OR REPLACE FUNCTION FUNC_WITH_VARRAY()
RETURNS VARCHAR(60)[]
LANGUAGE plpgsql AS $$
DECLARE
ARR VARCHAR(60)[] default array[]::VARCHAR(60)[];
BEGIN
ARR := ARRAY(SELECT NAME FROM TABLE_FOR_BULK);
RETURN ARR;
END; $$;
В результате программное обеспечение Конвертум корректно конвертирует BULK COLLECT из Oracle в PostgreSQL.
Если у вас есть другие вопросы, пожалуйста, свяжитесь с нами: support@convertum.ru