Създайте потребител чрез процедура в друга база данни чрез връзка към база данни

Бих искал да създам потребители чрез процедура в друга база данни чрез връзка към база данни. Получавам грешка при изпълнение на процедура. Ето кода, който използвах.

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: в "SYS.HOSTNAME", ред 6 ORA-06512: в ред 1
00900. 00000 - "невалиден SQL израз"
*Причина:
*Действие:


person Rahul Joshi    schedule 17.01.2015    source източник
comment
Мисля, че трябва да използвате анонимен блок, за да извикате процедура.   -  person mustaccio    schedule 17.01.2015
comment
Здравей mustaccio, той работи с анонимен блок, който опитах, но трябва да напиша процедура за предния край, така че предният край да може да го извика по всяко време   -  person Rahul Joshi    schedule 17.01.2015
comment
Наистина не трябва да създавате обекти в SYS схемата. Трябва да създадете свой собствен потребител/схема и да използвате само това. Трябва да се свързвате само като SYS, за да изпълнявате конкретни задачи на DBA.   -  person Alex Poole    schedule 17.01.2015


Отговори (1)


Мисля, че може да сте се объркали малко от някои от съветите, дадени от коментатора mustaccio. Това, което искаше да каже, е, че SQL низовете във вашите EXECUTE IMMEDIATE изрази трябва да използват 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;
/
person Luke Woodward    schedule 17.01.2015