[英]run DBMS_SCHEDULER.create_job from sys for a stored procedure owned by another schema [Oracle SQL]
[英]How to Move a Stored Procedure in Oracle SQL from one Schema to Another?
我试图了解我需要采取哪些步骤才能将存储过程从一个模式移动到另一个模式。 当前所在的模式将变得多余,我被要求移动所有表和过程。 我对表格没有任何问题,但从未对程序做过任何事情,因此我想确保我不会错过任何东西。
我目前所做的是查看该过程并列出其实际执行的操作,即删除/创建数据并将数据插入表中。
在此之后,我不确定这是否只是复制过程代码然后使用相同代码在新模式上创建新过程然后编译它的情况。
如果有人可以建议我是否在我正在执行的步骤中遗漏任何内容,我将非常感激,以确保我不会把事情搞砸。
没有办法将 object 从一个模式“移动”到另一个模式。
我在这里看到的唯一可行的方法是复制源代码,然后在新模式中执行它。 正如@pmdba 作为评论所写的那样,您应该注意“MYSCHEMA”。“TABLENAME”等模式名称和其他引用。
如果要复制的内容太多,可以考虑编写一个块,在其中自动读取旧模式的数据并在新模式中自动创建它。 你可以得到(几乎)一切的数据,即程序:
select * from all_source where owner = 'OLDSCHEMANAME' and type = 'PROCEDURE';
并像这样使用它:
begin
....
select listagg(text, '') within group (order by line) into proc_code
from all_source
where owner = 'OLDSCHEMANAME'
and type = 'PROCEDURE'
group by name;
execute immediate 'create or replace ' || proc_code; -- perhaps you need to remove the last ';' here
...
end;
请注意,此代码仅作为提示,不需要完全按照这种方式。 此外,由于不存在的对象、错误的模式引用等,您仍然可能会遇到错误。
要获取表的 ddl,可以使用select dbms_metadata.get_ddl('TABLE','Table_name','Schema_Name') from dual;
. 通过 谷歌搜索 dbms_metadata.get_ddl ,您可能会获得有关 DBMS_METADATA 包以及如何正确使用它的更多信息。
如前所述,没有机制可以将一个 object(过程 function 或 package 等)复制到另一个模式。 一种替代方法是使用 all_source,但我更喜欢DBMS_METADATA ,因为它允许您传输所有依赖项,例如权限。 想象一下,我需要复制一个程序,但我需要保留权限,有了这个 package,我可以得到一切。
例子
SQL> create procedure myschema1.my_procedure ( p1 number )
2 as
3 var1 number := p1;
4 begin
5 select 1 into var1 from dual;
6 end;
7 /
Procedure created.
SQL> grant execute on myschema1.my_procedure to myuser ;
Grant succeeded.
现在,假设我们想要将过程及其权限复制到另一个模式
SQL> set long 99999999 set lines 200 pages 400
SQL> select dbms_metadata.get_ddl('PROCEDURE','MY_PROCEDURE','MYSCHEMA1') from dual ;
DBMS_METADATA.GET_DDL('PROCEDURE','MY_PROCEDURE','MYSCHEMA1')
--------------------------------------------------------------------------------
CREATE OR REPLACE EDITIONABLE PROCEDURE "MYSCHEMA1"."MY_PROCEDURE" ( p1 number )
as
var1 number := p1;
begin
select 1 into var1 from dual;
end;
但是,想象一下你不想要引用,也不想要可编辑的论点
SQL> select
replace(dbms_metadata.get_ddl('PROCEDURE','MY_PROCEDURE','MYSCHEMA1','11.2.0'),'"','') as ddl from dual ;
DDL
--------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE MYSCHEMA1.MY_PROCEDURE ( p1 number )
as
var1 number := p1;
begin
select 1 into var1 from dual;
end;
然后为了获得新模式所有者的最终命令,我们使用 regexp_replace 替换第一次出现
SQL> select regexp_replace(replace(dbms_metadata.get_ddl('PROCEDURE','MY_PROCEDURE','MYSCHEMA1','11.2.0'),'"',''),'MYSCHEMA1','MYSCHEMA2',1,1)
2 as ddl from dual ;
DDL
--------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE MYSCHEMA2.MY_PROCEDURE ( p1 number )
as
var1 number := p1;
begin
select 1 into var1 from dual;
end;
最后,我们可以通过
SQL> select dbms_metadata.get_dependent_ddl( 'OBJECT_GRANT' , 'MY_PROCEDURE' , 'MYSCHEMA1' ) from dual ;
DBMS_METADATA.GET_DEPENDENT_DDL('OBJECT_GRANT','MY_PROCEDURE','MYSCHEMA1')
--------------------------------------------------------------------------------
GRANT EXECUTE ON "MYSCHEMA1"."MY_PROCEDURE" TO "MYUSER"
记得在开始一些设置之前在 session 级别申请以增强 dbms_metadata output:
begin
DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'SQLTERMINATOR', true);
DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'PRETTY', true);
end;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.