ITPub博客

首页 > 数据库 > Oracle > ORACLE中存储过程的权限问题

ORACLE中存储过程的权限问题

原创 Oracle 作者:goodlatch 时间:2015-03-16 20:56:06 0 删除 编辑
或许你也遇到过同样的问题:
用sql语句建表没问题,但是放到存储过程里执行就报没有权限;
用sql查询或dml操作也是没问题,放到存储过程就报错权限不足,或表不存在.

在官方文档上看到有这么一段话 ,文档地址 http://docs.oracle.com/cd/E11882_01/network.112/e36292/authorization.htm#i1007304 

How Roles Work in PL/SQL Blocks
The use of roles in a PL/SQL block depends on whether it is an anonymous block or a named block (stored procedure, function, or trigger), and whether it executes with definer's rights or invoker's rights.
Roles Used in Named Blocks with Definer's Rights
All roles are disabled in any named PL/SQL block (stored procedure, function, or trigger) that executes with definer's rights. Roles are not used for privilege checking and you cannot set roles within a definer's rights procedure.
The SESSION_ROLES view shows all roles that are currently enabled. If a named PL/SQL block that executes with definer's rights queries SESSION_ROLES, then the query does not return any rows.
Roles Used in Named Blocks with Invoker's Rights and Anonymous PL/SQL Blocks
Named PL/SQL blocks that execute with invoker's rights and anonymous PL/SQL blocks are executed based on privileges granted through enabled roles. Current roles are used for privilege checking within an invoker's rights PL/SQL block. You can use dynamic SQL to set a role in the session.


其大意就是说用户角色的权限在命名的pl/sql块里是不可用的,包括存储过程、触发器、函数,但是在匿名的pl/sql块里是没问题的。
什么是角色的权限呢?
可以通过dba_roles查看所有角色:select * from dba_roles;
可以通过user_role_privs及role_sys_privs查看用户有那些角色,及角色具有的权限。 用户在这两个视图中的权限在存储过程、触发器、函数中是不起作用的。


下面演示DDL的实验,用scott用户建一个存储过程来删除表和创建表

  1. SQL> set linesize 1000
  2. SQL> show user;
  3. USER is "SCOTT"
  4. SQL> col text format a80
  5. SQL> select line,text from user_source where type='PROCEDURE' and name='P_EMP1' ORDER BY LINE;

  6.       LINE TEXT
  7. ---------- --------------------------------------------------------------------------------
  8.      1 procedure p_emp1
  9.      2 as
  10.      3 begin
  11.      4 execute immediate 'drop table emp1';
  12.      5 execute immediate 'create table emp1 as select * from emp';
  13.      6 end;

  14. 6 rows selected.

  15. SQL> drop table emp1;

  16. Table dropped.

  17. SQL> create table emp1 as select * from emp;

  18. Table created.

  19. SQL>
  20. SQL> exec p_emp1;
  21. BEGIN p_emp1; END;

  22. *
  23. ERROR at line 1:
  24. ORA-01031: insufficient privileges
  25. ORA-06512: at "SCOTT.P_EMP1", line 5
  26. ORA-06512: at line 1
发现用sql语句直接运行create table emp1 as select * from emp 是没有问题的,但是在存储过程中提示权限不足。
来查一下scott用户有哪些系统权限


  1. SQL> select * from session_roles;

  2. ROLE
  3. ------------------------------
  4. CONNECT
  5. RESOURCE

  6. SQL> select * from role_sys_privs order by role;

  7. ROLE             PRIVILEGE                ADM
  8. ------------------------------ ---------------------------------------- ---
  9. CONNECT          CREATE SESSION                NO
  10. RESOURCE         CREATE CLUSTER                NO
  11. RESOURCE         CREATE INDEXTYPE             NO
  12. RESOURCE         CREATE OPERATOR                NO
  13. RESOURCE         CREATE PROCEDURE             NO
  14. RESOURCE         CREATE SEQUENCE                NO
  15. RESOURCE         CREATE TABLE                NO
  16. RESOURCE         CREATE TRIGGER                NO
  17. RESOURCE         CREATE TYPE                NO

  18. 9 rows selected.

  19. SQL> select * from user_sys_privs;

  20. USERNAME         PRIVILEGE                ADM
  21. ------------------------------ ---------------------------------------- ---
  22. SCOTT             UNLIMITED TABLESPACE            NO
scott有CONNECT和RESOURCE两个角色的权限,还有一个UNLIMITED TABLESPACE的系统权限。
接下来,给scott分配create table的权限,在看看效果


  1. SQL> conn /as sysdba
  2. Connected.
  3. SQL> grant create table to scott;

  4. Grant succeeded.

  5. SQL> conn scott/scott
  6. Connected.
  7. SQL> select * from user_sys_privs;

  8. USERNAME         PRIVILEGE                ADM
  9. ------------------------------ ---------------------------------------- ---
  10. SCOTT             UNLIMITED TABLESPACE            NO
  11. SCOTT             CREATE TABLE                NO

  12. SQL> exec p_emp1;
  13. BEGIN p_emp1; END;

  14. *
  15. ERROR at line 1:
  16. ORA-00942: table or view does not exist
  17. ORA-06512: at "SCOTT.P_EMP1", line 4
  18. ORA-06512: at line 1
  19. --这里报错是因为刚刚运行存储过程的时候已经drop掉emp1表了,但是create时候报错,所以这是会报表不存在

  20. SQL> create table emp1 as select * from emp;

  21. Table created.

  22. SQL> exec p_emp1;

  23. PL/SQL procedure successfully completed.
给scott分批create table的权限后,我们可以通过user_sys_privs视图看到scott拥有的权限,这时候存储过程正常了。

*********************************************************************************************************


接下来测试下dml操作,给scott用户dba的角色,然后让scott用户操作test用户下的表


  1. SQL> conn /as sysdba
  2. Connected.
  3. SQL> grant dba to scott;

  4. Grant succeeded.

  5. SQL> conn scott/scott
  6. Connected.
  7. SQL>
  8. SQL> select * from role_sys_privs order by role;

  9. ROLE             PRIVILEGE                ADM
  10. ------------------------------ ---------------------------------------- ---
  11. CONNECT          CREATE SESSION                NO
  12. DATAPUMP_EXP_FULL_DATABASE CREATE SESSION                NO
  13. DATAPUMP_EXP_FULL_DATABASE CREATE TABLE                NO
  14. DATAPUMP_IMP_FULL_DATABASE ALTER DATABASE                NO
  15. DATAPUMP_IMP_FULL_DATABASE ALTER PROFILE                NO
  16. DATAPUMP_IMP_FULL_DATABASE ALTER RESOURCE COST            NO
  17. DATAPUMP_IMP_FULL_DATABASE ALTER USER                NO
  18. DATAPUMP_IMP_FULL_DATABASE AUDIT ANY                NO
  19. DATAPUMP_IMP_FULL_DATABASE AUDIT SYSTEM                NO
  20. DATAPUMP_IMP_FULL_DATABASE CREATE PROFILE                NO
  21. DATAPUMP_IMP_FULL_DATABASE CREATE SESSION                NO

  22. ROLE             PRIVILEGE                ADM
  23. ------------------------------ ---------------------------------------- ---
  24. DATAPUMP_IMP_FULL_DATABASE DELETE ANY TABLE             NO
  25. DATAPUMP_IMP_FULL_DATABASE EXECUTE ANY OPERATOR            NO
  26. DATAPUMP_IMP_FULL_DATABASE GRANT ANY OBJECT PRIVILEGE        NO
  27. DATAPUMP_IMP_FULL_DATABASE GRANT ANY PRIVILEGE            NO
  28. DATAPUMP_IMP_FULL_DATABASE GRANT ANY ROLE                NO
  29. DATAPUMP_IMP_FULL_DATABASE SELECT ANY TABLE             NO
  30. DBA             ADMINISTER ANY SQL TUNING SET        YES
  31. DBA             ADMINISTER DATABASE TRIGGER        YES
  32. DBA             ADMINISTER RESOURCE MANAGER        YES
  33. DBA             ADMINISTER SQL MANAGEMENT OBJECT     YES
  34. DBA             ADMINISTER SQL TUNING SET        YES
  35. ...
  36. --下边有很多就不显示了,我们可以看到dba角色的权限已经有了


  37. SQL> set linesize 100
  38. SQL> desc test.t;
  39.  Name                         Null?    Type
  40.  ----------------------------------------------------- -------- ------------------------------------
  41.  ID                                NUMBER

  42. SQL> select * from test.t;

  43.     ID
  44. ----------
  45.      1

  46. SQL>

  47. SQL> select line,text from user_source where type='PROCEDURE' and name='P_INSERT_T' ORDER BY LINE;

  48.       LINE TEXT
  49. ---------- --------------------------------------------------------------------------------
  50.      1 procedure p_insert_t as
  51.      2 begin
  52.      3 insert into test.t values (2);
  53.      4 end;

  54. SQL> insert into test.t values (2);   --可以看到直接insert是没有问题的

  55. 1 row created.

  56. SQL> select * from test.t;

  57.     ID
  58. ----------
  59.      1
  60.      2

  61. SQL> rollback;

  62. Rollback complete.

  63. SQL> exec p_insert_t;
  64. BEGIN p_insert_t; END;

  65.       *
  66. ERROR at line 1:
  67. ORA-06550: line 1, column 7:
  68. PLS-00905: object SCOTT.P_INSERT_T is invalid
  69. ORA-06550: line 1, column 7:
  70. PL/SQL: Statement ignored

  71. --这里报了sql无效,我们编译下存储过程看看报什么错误

  72. SQL> alter procedure p_insert_t compile;

  73. Warning: Procedure altered with compilation errors.

  74. SQL> show errors;
  75. Errors for PROCEDURE P_INSERT_T:

  76. LINE/COL ERROR
  77. -------- -----------------------------------------------------------------
  78. 3/3     PL/SQL: SQL Statement ignored
  79. 3/20     PL/SQL: ORA-00942: table or view does not exist
  80. --这里报表不存在,说明没有对test用户的t表的select权限,我们来赋下权限
  1. SQL>
  2. SQL> conn test/test
  3. Connected.
  4. SQL> grant select on t to scott;

  5. Grant succeeded.

  6. SQL> conn scott/scott
  7. Connected.
  8. SQL> alter procedure p_insert_t compile;

  9. Warning: Procedure altered with compilation errors.

  10. SQL> show errors;
  11. Errors for PROCEDURE P_INSERT_T:

  12. LINE/COL ERROR
  13. -------- -----------------------------------------------------------------
  14. 3/3     PL/SQL: SQL Statement ignored
  15. 3/20     PL/SQL: ORA-01031: insufficient privileges
  16. --这时候开始报没有insert权限,继续赋权
  17. SQL>
  18. SQL>
  19. SQL> conn test/test
  20. Connected.
  21. SQL> grant insert on t to scott;

  22. Grant succeeded.

  23. SQL> conn scott/scott
  24. Connected.
  25. SQL> alter procedure p_insert_t compile;

  26. Procedure altered.

  27. SQL> select * from test.t;

  28.     ID
  29. ----------
  30.      1

  31. SQL> exec p_insert_t;

  32. PL/SQL procedure successfully completed.

  33. SQL> select * from test.t;

  34.     ID
  35. ----------
  36.      1
  37.      2
  38. --最后我们查下scott都有那些表才操作权限
  39. SQL> select * from user_tab_privs;

  40. GRANTEE          OWNER             TABLE_NAME         GRANTOR             PRIVILEGE                 GRA HIE
  41. ------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------------------------------------- --- ---
  42. SCOTT             TEST             T              TEST             INSERT                 NO NO
  43. SCOTT             TEST             T              TEST             SELECT                 NO NO

 所以在处理存储过程的时候要注意这些权限问题,不要只看用户的角色。

******************************************************************************************************************

我们总是想偷偷懒,每次都要赋权限感觉好麻烦,有没有其他好办法呢?答案是:有。oracle提供了一个authid的属性

  1. SQL> conn /as sysdba
  2. Connected.
  3. SQL> revoke create table from scott;

  4. Revoke succeeded.

  5. SQL> conn scott/scott
  6. Connected.

  7. SQL> select * from user_sys_privs;

  8. USERNAME         PRIVILEGE                ADM
  9. ------------------------------ ---------------------------------------- ---
  10. SCOTT             UNLIMITED TABLESPACE            NO

  11. SQL> select line,text from user_source where type='PROCEDURE' and name='P_EMP1' ORDER BY LINE;

  12.       LINE TEXT
  13. ---------- --------------------------------------------------------------------------------
  14.      1 procedure p_emp1
  15.      2 authid CURRENT_USER  --注意这里,多了一句
  16.      3 as
  17.      4 begin
  18.      5 execute immediate 'drop table emp1';
  19.      6 execute immediate 'create table emp1 as select * from emp';
  20.      7 end;

  21. 7 rows selected.

  22. SQL> exec p_emp1;

  23. PL/SQL procedure successfully completed.

添加一个authid CURRENT_USER就可以了,当然这么做也有一点风险,就是如果scott和test用户都有一个emp表,那么当test用户执行的时候,新建的emp1表会在test用户下


  1. SQL> select line,text from user_source where type='PROCEDURE' and name='P_EMP1' ORDER BY LINE;

  2.       LINE TEXT
  3. ---------- --------------------------------------------------------------------------------
  4.      1 procedure p_emp1
  5.      2 authid CURRENT_USER
  6.      3 as
  7.      4 begin
  8.      5 execute immediate 'create table emp1 as select * from emp'; --这里我们去掉了drop的语句
  9.      6 end;

  10. 6 rows selected.

  11. SQL> conn / as sysdba
  12. Connected.
  13. SQL>
  14. SQL>
  15. SQL> select owner,table_name from dba_tables where table_name='EMP1';

  16. OWNER             TABLE_NAME
  17. ------------------------------ ------------------------------
  18. SCOTT             EMP1

  19. SQL> drop table scott.emp1;

  20. Table dropped.

  21. SQL> grant resource to test;

  22. Grant succeeded.

  23. SQL> grant execute on scott.p_emp1 to test;

  24. Grant succeeded.

  25. SQL> conn test/test;
  26. Connected.
  27. SQL> create table emp (id number) ;

  28. Table created.

  29. SQL> exec scott.p_emp1;

  30. PL/SQL procedure successfully completed.

  31. SQL> conn /as sysdba
  32. Connected.

  33. SQL> select owner,table_name from dba_tables where table_name='EMP1';

  34. OWNER             TABLE_NAME
  35. ------------------------------ ------------------------------
  36. TEST             EMP1

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29339009/viewspace-1462017/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: oracle静默安装
请登录后发表评论 登录
全部评论

注册时间:2013-11-27

  • 博文量
    6
  • 访问量
    22055