使用 Aws SCT 工具将 Oracle 包转换为 PostgreSQL 的命名问题
Naming issues on Oracle Packages conversion to PostgreSQL using Aws SCT tool
我已经在 AWS SCT 工具的帮助下将 Oracle 数据库迁移到 Aurora postgreSQL。
所有包和触发器在 PostgreSQL 中都转换为函数。我的问题是所有名称都用 $
(美元)符号转换。
例如,Oracle pk_audit.sp_get_audit
中的一个包和关联的存储过程转换为带有 $ 符号的 pk_audit$sp_get_audit
postgreSQL。但是,在中间件数据库对象名称是 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;`
但是结果是抛出错误。请帮忙谢谢
这行不通。即使您生成的语句具有有效的语法,它也会失败,除非您为每个 Oracle 包创建了一个 Postgres 模式。 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 函数和中间件中的一个或两个。
所以基本上 运行 转换脚本只是转换过程中许多步骤的第一步。
祝你好运!
注意:上面提到的过程指的是过程和函数。
试试这个:
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)
最简单的解决方案是使用 psql
的 \gexec
功能:
SELECT format(
'ALTER FUNCTION %s RENAME TO %I',
oid::regprocedure,
replace(proname, '$', '.')
)
FROM pg_proc
WHERE pronamespace::regnamespace::text = 'my_schema' \gexec
我已经在 AWS SCT 工具的帮助下将 Oracle 数据库迁移到 Aurora postgreSQL。
所有包和触发器在 PostgreSQL 中都转换为函数。我的问题是所有名称都用 $
(美元)符号转换。
例如,Oracle pk_audit.sp_get_audit
中的一个包和关联的存储过程转换为带有 $ 符号的 pk_audit$sp_get_audit
postgreSQL。但是,在中间件数据库对象名称是 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;`
但是结果是抛出错误。请帮忙谢谢
这行不通。即使您生成的语句具有有效的语法,它也会失败,除非您为每个 Oracle 包创建了一个 Postgres 模式。 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 函数和中间件中的一个或两个。
所以基本上 运行 转换脚本只是转换过程中许多步骤的第一步。
祝你好运!
注意:上面提到的过程指的是过程和函数。
试试这个:
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)
最简单的解决方案是使用 psql
的 \gexec
功能:
SELECT format(
'ALTER FUNCTION %s RENAME TO %I',
oid::regprocedure,
replace(proname, '$', '.')
)
FROM pg_proc
WHERE pronamespace::regnamespace::text = 'my_schema' \gexec