Проблемы с именами при Oracle преобразовании пакетов в PostgreSQL с использованием Aws инструмента SCT - PullRequest
0 голосов
/ 02 апреля 2020

Я перенес Oracle дБ в Аврору postgreSQL с помощью инструмента AWS SCT. Все пакеты и триггеры конвертируются как функции в PostgreSQL. Моя проблема здесь заключается в том, что все имена конвертированы с символом $ (доллар).

например, пакет и связанный с ним сохраненный pro c в Oracle pk_audit.sp_get_audit, преобразованный в postgreSQL как pk_audit$sp_get_audit с символом $. но в промежуточном программном обеспечении имя объекта базы данных pk_audit.sp_get_audit. Чтобы минимизировать нагрузку на промежуточное ПО, мне нужно преобразовать все функции из pk_audit$sp_get_audit в pk_audit.sp_get_audit.

У меня более 1500 функций, преобразованных с помощью символа $. Нужен скрипт для изменения всех имен пользовательских функций. Я создал сценарий для создания сценариев изменения.

`select a.alter_statement|| replace(a.rename_statement,'$','.')
From
(
SELECT format('ALTER %s %I.%I(%s)'
            , 'FUNCTION'
              ,CONCAT('"',n.nspname,'"') 
            , p.proname
            , pg_catalog.pg_get_function_identity_arguments(p.oid)
             ) AS alter_statement,
             format('RENAME %s %I.%I(%s);'
            , 'TO' 
            , CONCAT('"',n.nspname,'"') 
            , p.proname
            , pg_catalog.pg_get_function_identity_arguments(p.oid)
             ) AS rename_statement
FROM   pg_catalog.pg_proc p
JOIN   pg_catalog.pg_namespace n ON n.oid = p.pronamespace
and     n.nspname = 'my_schema' ORDER  BY 1
) a;`

Но в результате выдается ошибка. Пожалуйста, помогите спасибо

Ответы [ 3 ]

2 голосов
/ 02 апреля 2020

Попробуйте это:

select a.alter_statement|| replace(a.rename_statement,'$','.')
From
(
SELECT format('ALTER FUNCTION %s.%s(%s) '
              ,CONCAT(n.nspname) 
              , p.proname
              , pg_catalog.pg_get_function_identity_arguments(p.oid)
             ) AS alter_statement,
             format('RENAME TO %I'
             ,p.proname
             ) AS rename_statement
FROM   pg_catalog.pg_proc p
JOIN   pg_catalog.pg_namespace n ON n.oid = p.pronamespace
and     n.nspname = 'newschema' ORDER  BY 1
) a;

Пример:

select a.alter_statement|| replace(a.rename_statement,'$','.')
From
(
SELECT format('ALTER FUNCTION %s.%s(%s) '
              ,CONCAT(n.nspname) 
              , p.proname
              , pg_catalog.pg_get_function_identity_arguments(p.oid)
             ) AS alter_statement,
             format('RENAME TO %I'
             ,p.proname
             ) AS rename_statement
FROM   pg_catalog.pg_proc p
JOIN   pg_catalog.pg_namespace n ON n.oid = p.pronamespace
and     n.nspname = 'newschema' ORDER  BY 1
) a;
                                    ?column?                                     
---------------------------------------------------------------------------------
 ALTER FUNCTION newschema.package$function(integer) RENAME TO "package.function"
(1 row)
1 голос
/ 03 апреля 2020

Самое простое решение - использовать функцию \gexec psql:

SELECT format(
          'ALTER FUNCTION %s RENAME TO %I',
          oid::regprocedure,
          replace(proname, '$', '.')
       )
FROM pg_proc
WHERE pronamespace::regnamespace::text = 'my_schema' \gexec
1 голос
/ 02 апреля 2020

Это не будет работать. Даже если ваш сгенерированный оператор имеет допустимый синтаксис, он потерпит неудачу, если вы не создали схему Postgres для каждого пакета Oracle. Пакеты Oracle объединяют несколько процедур в один объект базы данных. К сожалению, Postgres не имеет такой концепции, поэтому каждая процедура в пакете становится независимой функцией Postgres. Это приводит к проблеме структуры имен за пределами $ в имени. В Oracle ссылка на формат имя_пакета.procedure_name говорит, что нужно запускать имя процедуры, которое находится внутри имени пакета, та же строка кода в Postgres интерпретируется как имя_ф_ф_функции_функции, Вот почему процедура преобразования заменяет его на имя_пакета $ имя_процесса , которое все еще является действительным Postgres в имени той же схемы. (В зависимости от длины переведенного имени; что делает процедура перевода, когда общая длина имени пакета_имя + имя_процесса + 1 превышает предел длины имени в Postgres (63)?) Этот аспект может упростить общую работу системы по обновлению промежуточное программное обеспечение. И это только начало ваших проблем с конвертацией пакетов. Что о:

  • Типы уровней пакета, курсоры, переменные, коллекции и т. Д. c, определенные только в пакете spe c.
  • То же, что и выше, определенное только в теле пакета, но НЕ в какой-либо процедуре.
  • Ссылки на любой из вышеперечисленных, изнутри в результате функции Poatgres.
  • Другие функциональные возможности пакетов в Oracle, не переводимые напрямую в Postgres. Все они должны быть рассмотрены и, возможно, могут потребовать модификации одной или обеих функций Postgres и вашего промежуточного программного обеспечения. Таким образом, в основном запуск сценария конверсии - это только первый шаг в процессе из множества шагов для вашей конверсии. Удачи! ПРИМЕЧАНИЕ. Приведенная выше ссылка на процедуру относится как к процедурам, так и к функциям.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...