Naming issues on Oracle Packages conversion to PostgreSQL using Aws SCT tool

早过忘川 提交于 2020-04-18 05:35:13

问题


I had migrated Oracle db to Aurora postgreSQL with the help of AWS SCT tool. All packages and triggers are converted as functions in PostgreSQL. My issue here is all the names are converted with a $ (dollar) symbol.

for example, A package and associated stored proc in Oracle pk_audit.sp_get_audit converted to postgreSQL as pk_audit$sp_get_audit with a $ symbol. but, In the middleware db object name is pk_audit.sp_get_audit . In order to minimise the effort on the middleware, I need to convert all the functions from pk_audit$sp_get_audit to pk_audit.sp_get_audit.

I've more than 1500 functions converted with $ symbol. Need a script to alter all the User Defined Functions names . I've created a script to build the alter scripts.

`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;`

But the result is throwing error. Kindly help thanks


回答1:


Try this:

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;

Example:

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)



回答2:


This will not work. Even if your generated statement has a valid syntax it will fail, unless you have created a Postgres schema for each Oracle package. Oracle packages gather multiple procedures and into a single database object. Unfortunately Postgres has no such concept so each procedure within the package becomes an independent function is Postgres. This results in a naming structure issue beyond the $ in the name. In Oracle the format reference to package_name.procedure_name says to run procedure name that is within the package name, the same line of code in Postgres is interpreted as schema_name.function_name. That is why the conversion routine replaces it with package_name$procedure_name which is still a valid Postgres within name the same schema. (Subject to translated name length; what does the translation routine do when combined length of package_name + procedure_name + 1 is over the name length limit in Postgres (63)? ) That aspect may make it easier on an overall system effort to update the middleware. And that is just the beginnings of your package conversion issues. What about:

  • Package level types, cursors, variables, collections, etc defined only in the package spec.
  • The same as above defined only in the package body but NOT within any procedure.
  • References to either of the above, from within the resulting Poatgres functions.
  • Other functionality of packages in Oracle not directly translatable to Postgres. All of these must be looked at and may perhaps require modifications to either or both of the Postgres functions and your middleware. So basically running a conversion script is just the first step in a process of many steps for your conversion.

    Good Luck!
    NOTE: Reference in above to procedure refers to both procedures and functions.



回答3:


The easiest solution is to use the \gexec feature of psql:

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


来源:https://stackoverflow.com/questions/60996449/naming-issues-on-oracle-packages-conversion-to-postgresql-using-aws-sct-tool

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!