即使使用CREATE表grant,Execute Immediate也会失败

时间:2015-11-18 07:02:26

标签: database plsql oracle11g grant execute-immediate

我有一个问题,我在存储过程中使用execute immediate命令创建表。但是我得到了“权限不足”的错误。我检查了其他线程并确保用户具有授予它的“CREATE TABLE”权限。但是我仍然看到同样的错误。

SQL> select * from USER_SYS_PRIVS;

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

SQL> select * from session_privs;

PRIVILEGE
----------------------------------------
CREATE SESSION
UNLIMITED TABLESPACE
CREATE TABLE
CREATE CLUSTER
CREATE VIEW
CREATE SEQUENCE
CREATE PROCEDURE
CREATE TRIGGER
CREATE TYPE
CREATE OPERATOR
CREATE INDEXTYPE

11 rows selected.

我创建的虚拟程序是:

create or replace procedure sp_dummy
   as
   begin
      execute immediate 'Create table Dummy99_99 (Dummy_Field number)';
   end sp_dummy;
   /

详细错误:

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

我有什么问题吗?

4 个答案:

答案 0 :(得分:5)

您只有create view直接授予您的用户。您可以看到的其他系统权限来自角色,roles are disabled in definer's-rights stored procedures。查看user_role_privs以查看您已被授予的角色,并且您可以在role_sys_privs中查看每个角色为您提供的权限(角色名称为被授予者)。也可能有几层角色。

如果您在尝试静态创建表之前执行set role none,则会看到相同的错误。最少设置的演示:

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;

然后作为该用户:

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

使用您的存储过程版本:

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

为了能够从存储过程动态创建表,您的DBA需要直接向您的用户授予create table

grant create table to myuser;

然后再次尝试该程序:

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

请注意,user_sys_privs现在显示create table已被直接授予,而之前没有或在问题中。{/ p>

但是,您不太可能真正想要动态创建对象,因为架构应该定义良好且稳定 - 应该控制此类型的更改并成为发布过程的一部分。但作为练习,你需要直接拨款。

答案 1 :(得分:2)

如果您以myuser用户身份连接,您应该能够创建该过程,并执行该过程以创建该表。

执行任务所需的唯一权限是:

  • 创建会话
  • 创建表格
  • 创建程序

然后在连接到用户后执行该过程:

SQL> CREATE USER TEST IDENTIFIED BY TEST;

User created.

SQL> GRANT CREATE SESSION, CREATE TABLE, CREATE PROCEDURE TO TEST;

Grant succeeded.

SQL> conn TEST/TEST@pdborcl;
Connected.
SQL> show user
USER is "TEST"
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;

PL/SQL procedure successfully completed.

SQL> select * from dummy99_99;

no rows selected

答案 2 :(得分:2)

使用execute immediate时,procedure必须明确告诉oracle它必须以特定用户的权限运行。

AUTHID CURRENT_USER,使用运行该过程的用户的权限。 AUTHID DEFINER,使用过程所有者的权限。

这是在创建过程时使用AUTHID选项完成的。

CREATE OR REPLACE PROCEDURE PROC_NAME AUTHID CURRENT_USER
IS
.....

我遇到了类似的问题并得到了以下理解: Execute Immediate within a stored procedure keeps giving insufficient priviliges error

答案 3 :(得分:-1)

必要的让步如下:

GRANT CREATE TABLE TO" USER&#34 ;; 授予执行任何程序"用户" ;