我想通过数据库链接在另一个数据库上通过过程创建用户。我在执行程序时出错。这是我使用的代码。
create or REPLACE PROCEDURE hostname
(host_name in varchar2,user_name in VARCHAR2, pass_word in VARCHAR2,
table_space in varchar2,pro_file in varchar2)
as
db_link_name varchar2(30);
begin
select db_link into db_link_name from all_db_links where host=host_name;
EXECUTE IMMEDIATE 'dbms_utility.exec_ddl_statement@'||db_link_name||('CREATE USER '||user_name||' IDENTIFIED BY '||pass_word||'
DEFAULT TABLESPACE '||table_space||' PROFILE '|| pro_file||' ACCOUNT UNLOCK');
EXECUTE IMMEDIATE 'dbms_utility.exec_ddl_statement@'||db_link_name||
('GRANT CONNECT,RESOURCE,EXECUTE_CATALOG_ROLE,Create table,create session,create view,create sequence,create procedure,create job,create synonym TO '||user_name);
end;
/
execute hostname('orcl1','rahul1','rahul','users','default');
错误: ORA-00900:无效的 SQL 语句 ORA-06512: 在 "系统。主机名",第 6 行 ORA-06512:在第 1
行 00900. 00000 - "无效的 SQL 语句"
*原因:
*行动:
我想你可能对评论者mustaccio提供的一些建议感到有些困惑。 他的意思是,EXECUTE IMMEDIATE
语句中的 SQL 字符串需要使用 PL/SQL 块才能调用存储过程。
换句话说,而不是写作
EXECUTE IMMEDIATE 'dbms_utility.exec_ddl_statement ... ';
你应该写
EXECUTE IMMEDIATE 'BEGIN dbms_utility.exec_ddl_statement ... ; END;';
对于您的过程,我建议您为要传递给EXECUTE IMMEDIATE
的字符串引入局部变量。 众所周知,这些可能很难正确处理,如果您将它们分配给局部变量,您可以使用 dbms_output.put_line
轻松输出它们。 事实上,我在修复您程序中的问题时正是这样做的。 如果您希望修改或扩展您的程序,我建议您继续这样做。
无论如何,这是我最终得到的,它似乎有效:
create or REPLACE PROCEDURE hostname
(host_name in varchar2,user_name in VARCHAR2, pass_word in VARCHAR2,
table_space in varchar2,pro_file in varchar2)
as
db_link_name varchar2(30);
l_ddl_sql varchar2(4000);
begin
select db_link into db_link_name from all_db_links where host=host_name;
l_ddl_sql := 'begin dbms_utility.exec_ddl_statement@'||db_link_name||'(''CREATE USER '||user_name||' IDENTIFIED BY '||pass_word||'
DEFAULT TABLESPACE '||table_space||' PROFILE '|| pro_file||' ACCOUNT UNLOCK''); END;';
EXECUTE IMMEDIATE l_ddl_sql;
l_ddl_sql := 'begin dbms_utility.exec_ddl_statement@'||db_link_name||
'(''GRANT CONNECT,RESOURCE,EXECUTE_CATALOG_ROLE,Create table,create session,create view,create sequence,create procedure,create job,create synonym TO '||user_name || '''); END;';
EXECUTE IMMEDIATE l_ddl_sql;
end;
/