如何制作数据库包的副本

时间:2014-06-11 05:55:16

标签: oracle plsql

我有一个包(可能很多),我想复制到一个名称不同的新包。

理想情况下,我想运行这个:

begin
  copy_package('MY_PACKAGE_NAME','MY_PACKAGE_NAME$BK');
end;
/

这将找到名为MY_PACKAGE_NAME的包,并创建/替换名为MY_PACKAGE_NAME$BK的新包,其中所有对MY_PACKAGE_NAME(如果有)的引用也会被更改。

假设包名称不区分大小写是合理的,并且源中对包名称的任何引用都将是全部大写或全部小写(即,不会引用{{1在源中)。

1 个答案:

答案 0 :(得分:4)

此过程将复制指定的包,替换对包名称(全部大写或小写)的任何引用 - 包括注释中的任何引用。

procedure copy_package
  (old_name IN VARCHAR2
  ,new_name IN VARCHAR2
  ) is
  ddl clob;
begin
  ddl := dbms_metadata.get_ddl
    (object_type => 'PACKAGE_SPEC'
    ,name => old_name
    );
  ddl := REPLACE(ddl, UPPER(old_name), UPPER(new_name));
  ddl := REPLACE(ddl, LOWER(old_name), LOWER(new_name));
  EXECUTE IMMEDIATE ddl;
  ddl := dbms_metadata.get_ddl
    (object_type => 'PACKAGE_BODY'
    ,name => old_name);
  ddl := REPLACE(ddl, UPPER(old_name), UPPER(new_name));
  ddl := REPLACE(ddl, LOWER(old_name), LOWER(new_name));
  EXECUTE IMMEDIATE ddl;
end copy_package;

如果架构中已存在新的软件包名称,它将被覆盖而不会发出警告。

旧包装保持不变。

如果需要任何拨款或同义词,则不会复制它们。

如果软件包的代码恰好包含较长标识符中的软件包名称(例如NOT_MY_PACKAGE_NAME),则会失败,因为它会不加选择地替换该文本。

如果包规格或正文大小超过32K,则此过程将失败。

如果未找到包装规格或正文,则此程序会引发ORA-31603。如果找到了规范但是身体没有,则会复制规范,然后它会引发异常。