Создать пользователя через процедуру в другой базе данных через ссылку на базу данных

Я хочу создать пользователей через процедуру в другой базе данных через ссылку на базу данных. Я получаю сообщение об ошибке при выполнении процедуры. Вот код, который я использовал.

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