5

我在存储过程中使用执行立即命令创建表时遇到问题。但是我得到“权限不足”的错误。我检查了其他线程并确保用户已授予它“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

4 回答 4

10

您只create view直接授予您的用户。您可以看到的其他系统权限来自角色,并且角色在定义者权限存储过程中被禁用。查看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已直接授予,而之前未授予,或在问题中。

但是,您不太可能真正想要动态地创建对象,因为模式应该定义明确且稳定 - 这种类型的更改应该受到控制并成为发布过程的一部分。但作为练习,您需要直接授权。

于 2015-11-18T08:17:40.517 回答
7

当使用立即执行时,过程必须明确告诉 oracle 它必须以特定用户的权限运行。

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

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

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

我遇到了类似的问题,并从中得到了理解: 在存储过程中执行立即不断给予不足的权限错误

于 2017-07-07T06:22:20.877 回答
4

如果您以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
于 2015-11-18T07:18:05.237 回答
-1

必要的让步如下:

GRANT CREATE TABLE TO "USER";
GRANT EXECUTE ANY PROCEDURE TO "USER" ;
于 2018-02-02T20:40:37.810 回答