我有一个问题,我在存储过程中使用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
我有什么问题吗?
答案 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 ;; 授予执行任何程序"用户" ;