mysql ora01031_ORA-01031: insufficient privileges

今天接到开发反馈,说数据库动态sql创建表语句无法执行,提示ORA-01031: insufficient privileges

1、数据库版本

SQL> select * from v$version where rownum=1;

BANNER

—————————————————————-

Oracle9i Enterprise Edition Release 9.2.0.4.0 – Production

2、创建用户并授权

SQL> create user test identified by xifenfei;

User created.

SQL> grant connect,resource to test;

Grant succeeded.

3、查看权限

SQL> SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE=’TEST’;

GRANTEE PRIVILEGE ADM

—————————— —————————————- —

TEST UNLIMITED TABLESPACE NO

SQL> SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTEE=’TEST’;

GRANTEE GRANTED_ROLE ADM DEF

—————————— —————————— — —

TEST CONNECT NO YES

TEST RESOURCE NO YES

SQL> CONN TEST/XIFENFEI

Connected.

SQL> SELECT * FROM SESSION_PRIVS;

PRIVILEGE

—————————————-

CREATE SESSION

ALTER SESSION

UNLIMITED TABLESPACE

CREATE TABLE

CREATE CLUSTER

CREATE SYNONYM

CREATE VIEW

CREATE SEQUENCE

CREATE DATABASE LINK

CREATE PROCEDURE

CREATE TRIGGER

PRIVILEGE

—————————————-

CREATE TYPE

CREATE OPERATOR

CREATE INDEXTYPE

14 rows selected.

注:目前create table权限是通过resource role授予test用户的

4、创建存储过程(Authid Current_User)

SQL> create or replace procedure create_table(t varchar2) Authid Current_User

2 is

3 P_SQL VARCHAR2(300);

4 BEGIN

5 P_SQL := ‘create table ‘||t||’ as select * from user_tables where 1=0′;

6 EXECUTE IMMEDIATE P_SQL;

END; 7

8 /

Procedure created.

5、执行存储过程

SQL> EXEC CREATE_table(‘a’);

PL/SQL procedure successfully completed.

6、重建存储过程(不包括Authid Current_User)

SQL> create or replace procedure create_table(t varchar2)

2 –Authid Current_User

3 is

4 P_SQL VARCHAR2(300);

5 BEGIN

6 P_SQL := ‘create table ‘||t||’ as select * from user_tables where 1=0′;

7 EXECUTE IMMEDIATE P_SQL;

8 END;

9 /

Procedure created.

SQL> EXEC CREATE_table(‘b’);

BEGIN CREATE_table(‘b’); END;

*

ERROR at line 1:

ORA-01031: insufficient privileges

ORA-06512: at “TEST.CREATE_TABLE”, line 7

ORA-06512: at line 1

7、授权(create table权限)

SQL> conn / as sysdba

Connected.

SQL> grant create table to test;

Grant succeeded.

SQL> conn test/xifenfei

Connected.

SQL> EXEC CREATE_table(‘c’);

PL/SQL procedure successfully completed.

8、查看结果

SQL> select * from tab;

TNAME TABTYPE CLUSTERID

—————————— ——- ———-

A TABLE

C TABLE

9、 查询资料

默认情况下,在调用存储过程用户的角色是不起作用的,即在执行存储过程时只有Public权限。所以如果被调用的存储过程中如果有execute immediate ‘create table..’语句,将会引发ORA-01031: insufficient privileges错误。

存储过程分为两种,即DR(Definer’s Rights ) Procedure和IR(Invoker’s Rights ) Procedure。为什么会有两种存储过程呢?其实考虑完下面的问题就清楚了。比如说用户hrch创建了删除表tar_table的存储过程drop_table(),当用户hrch调用时,即删除用户hrch下的表tar_table;如果是另一个用户scott调用呢?是删除用户scott下的tar_table表呢,还是删除用户hrch下的tar_table呢?另外,如果存储过程中包含建表语句,不管是用户hrch还是用户scott调用都会失败,因为Public没有建表权限,除非为Public grant建表权限。

10、动态sql中执行create table解决方案(10g也存在同样问题)

1)加上Authid Current_User

2)直接赋予create table to 该用户

11、匿名块的动态sql不在此限制中

SQL> conn / as sysdba

Connected.

SQL> SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE=’TEST’;

GRANTEE PRIVILEGE ADM

—————————— —————————————- —

TEST UNLIMITED TABLESPACE NO

SQL> CONN TEST/XIFENFEI

Connected.

SQL> DECLARE

2 P_SQL VARCHAR2(300);

3 BEGIN

4 P_SQL := ‘create table t_t as select * from user_tables where 1=0′;

5 EXECUTE IMMEDIATE P_SQL;

6 END;

7 /

PL/SQL procedure successfully completed.


版权声明:本文为weixin_39759918原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。