ORA-01031: insufficient privileges

联系:手机(13429648788)  QQ(107644445)

链接:https://www.orasos.com/ora-01031-insufficient-privileges.html

标题: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.