Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Execute Immediate falha mesmo com a concessão de tabela CREATE


Você só tem create view concedido diretamente ao seu usuário. Os outros privilégios do sistema que você pode ver são provenientes de uma função e as funções estão desabilitadas nos procedimentos armazenados de direitos do definidor . Procure em user_role_privs para ver as funções que você recebeu e quais privilégios cada função oferece em role_sys_privs (com o nome da função como o beneficiário). Pode haver várias camadas de papéis também.

Você veria o mesmo erro se set role none antes de tentar criar uma tabela estaticamente. Demonstração com configuração mínima:
create role myrole;
grant create session, create table, create procedure to myrole;
create user myuser identified by mypasswd;
grant myrole to myuser;
grant create view, unlimited tablespace to myuser;

Então, como esse usuário:
SQL> connect myuser/mypasswd
Connected.
SQL> select * from user_sys_privs;

USERNAME                       PRIVILEGE                                ADM
------------------------------ ---------------------------------------- ---
MYUSER                         UNLIMITED TABLESPACE                     NO
MYUSER                         CREATE VIEW                              NO

2 rows selected.

SQL> select * from session_privs;

PRIVILEGE
----------------------------------------
CREATE SESSION
UNLIMITED TABLESPACE
CREATE TABLE
CREATE VIEW
CREATE PROCEDURE

5 rows selected.

SQL> Create table Dummy99_99 (Dummy_Field number);

Table created.

SQL> drop table Dummy99_99 purge;

Table dropped.

SQL> set role none;

Role set.

SQL> Create table Dummy99_99 (Dummy_Field number);
Create table Dummy99_99 (Dummy_Field number)
*
ERROR at line 1:
ORA-01031: insufficient privileges

E com sua versão de procedimento armazenado:
SQL> connect myuser/mypasswd
Connected.
SQL> create or replace procedure sp_dummy
  2  as
  3  begin
  4    execute immediate 'Create table Dummy99_99 (Dummy_Field number)';
  5  end sp_dummy;
  6  /

Procedure created.

SQL> exec sp_dummy;
BEGIN sp_dummy; END;

*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at "MYUSER.SP_DUMMY", line 4
ORA-06512: at line 1

Para poder criar a tabela dinamicamente a partir de um procedimento armazenado, seu DBA precisará conceder create table diretamente ao seu usuário:
grant create table to myuser;

Em seguida, tente o procedimento novamente:
SQL> connect myuser/mypasswd
Connected.
SQL> select * from user_sys_privs;

USERNAME                       PRIVILEGE                                ADM
------------------------------ ---------------------------------------- ---
MYUSER                         UNLIMITED TABLESPACE                     NO
MYUSER                         CREATE TABLE                             NO
MYUSER                         CREATE VIEW                              NO

SQL> exec sp_dummy;

PL/SQL procedure successfully completed.

SQL> desc Dummy99_99
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 DUMMY_FIELD                                        NUMBER

Observe que user_sys_privs agora mostra que create table foi concedido diretamente, o que não aconteceu antes, ou na questão.

No entanto, é muito improvável que você realmente queira criar objetos dinamicamente, pois o esquema deve ser bem definido e estável - alterações desse tipo devem ser controladas e fazer parte de um processo de liberação. Mas, como exercício, você precisa da subvenção direta.