Проблемы с именованием при преобразовании пакетов Oracle в PostgreSQL с помощью инструмента Aws SCT

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

например, пакет и связанный хранимый процесс в Oracle pk_audit.sp_get_audit преобразован в postgreSQL как pk_audit$sp_get_auditс символом $. но в промежуточном программном обеспечении имя объекта dbpk_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 ответа

Решение

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

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)

Самое простое решение - использовать \gexec особенность psql:

SELECT format(
          'ALTER FUNCTION %s RENAME TO %I',
          oid::regprocedure,
          replace(proname, '$', '.')
       )
FROM pg_proc
WHERE pronamespace::regnamespace::text = 'my_schema' \gexec

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

  • Типы уровня пакета, курсоры, переменные, коллекции и т. Д. Определены только в спецификации пакета.
  • То же, что и выше, определено только в теле пакета, но НЕ внутри какой-либо процедуры.
  • Ссылки на любой из вышеперечисленных в результирующих функциях Poatgres.
  • Прочие функции пакетов в Oracle не могут быть напрямую переведены в Postgres. На все это необходимо обратить внимание, и, возможно, может потребоваться модификация одной или обеих функций Postgres и вашего промежуточного программного обеспечения. Таким образом, запуск сценария преобразования - это только первый шаг в процессе преобразования, состоящем из множества этапов.

    Удачи!
    ПРИМЕЧАНИЕ. Приведенная выше ссылка на процедуру относится как к процедурам, так и к функциям.
Другие вопросы по тегам