Проблемы с именованием при преобразовании пакетов 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 и вашего промежуточного программного обеспечения. Таким образом, запуск сценария преобразования - это только первый шаг в процессе преобразования, состоящем из множества этапов.
Удачи!
ПРИМЕЧАНИЕ. Приведенная выше ссылка на процедуру относится как к процедурам, так и к функциям.