我有一个包(可能很多),我想将其复制到具有不同名称的新包中。
理想情况下,我想运行这个:
begin
copy_package('MY_PACKAGE_NAME','MY_PACKAGE_NAME$BK');
end;
/
Run Code Online (Sandbox Code Playgroud)
这将找到名为 的包MY_PACKAGE_NAME,并创建/替换一个名为 的新包,MY_PACKAGE_NAME$BK其中所有引用MY_PACKAGE_NAME(如果有)也已更改。
假设包名称不区分大小写是合理的,并且源中对包名称的任何引用都将全部为大写或全部小写(即My_Package_Name源中不会有任何引用)。
此过程将复制指定的包,同时替换对包名称(全部大写或小写)的任何引用 - 包括注释中的任何引用。
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;
Run Code Online (Sandbox Code Playgroud)
如果模式中已经存在新的包名称,它将在没有警告的情况下被覆盖。
旧包保持原样。
如果需要任何授权或同义词,则不会复制它们。
如果包的代码碰巧在更长的标识符(例如NOT_MY_PACKAGE_NAME)中包含包名称,这将失败,因为它将不加选择地替换该文本。
如果包规格或主体的大小大于 32K,则此过程将失败。
如果未找到包规范或正文,则此过程会引发 ORA-31603。如果找到了规范但没有找到正文,则将复制规范,然后引发异常。