Você só pode definir uma função em um procedimento/função armazenado PL/SQL se ele tiver Direitos do invocador (
AUTHID CURRENT_USER
)(ver doc)
. O que significa que você não pode usar ops_user para chamar o procedimento de admin_user e acessar as funções de admin_user. Se seus DBAs insistem em usar uma função para controlar o CREATE TABLE
privilégio, aqui está a abordagem que já vi antes:create or replace package admin_user.role_test authid current_user is
procedure test_permissions;
end role_test;
/
create or replace package body admin_user.role_test is
procedure test_permissions is
v_query_string VARCHAR2(400 CHAR) := 'begin
dbms_output.put_line(''after'');
for r in (select role from session_roles) loop
dbms_output.put_line(r.role);
end loop;
end;';
begin
dbms_output.put_line('before');
for r in (select role from session_roles) loop
dbms_output.put_line(r.role);
end loop;
DBMS_SESSION.SET_ROLE('CREATE_TABLE_ROLE IDENTIFIED BY "SECRET_PASSWORD"');
execute immediate v_query_string;
DBMS_SESSION.SET_ROLE('ALL EXCEPT CREATE_TABLE_ROLE'); -- restore defaults
end;
end role_test;
/
grant execute on admin_user.role_test to ops_user;
Isso concederá temporariamente o papel a ops_user apenas para executar seu código. Por padrão, o ops_user não deve ser capaz de visualizar a fonte do corpo do pacote do admin_user. Você provavelmente poderia envolver o corpo do pacote para proteger ainda mais a senha. Mas a segurança da senha à parte, minha maior preocupação com essa abordagem é que o Oracle não fornece uma boa maneira de desabilitar uma única função, portanto, se ops_user tiver outras funções protegidas por senha, esse código poderá gerar um ORA-01979 ao tentar restaurar eles.
Portanto, há uma resposta, mas ainda recomendo fazer o que os outros comentaristas sugeriram e conceder CREATE TABLE ao seu usuário administrador.