Oracle存储过程中的ORA-01031错误分析

在调用存储过程中,需要使用EXECUTE IMMEDIATE的方式动态创建临时表,运行的时候发生了下面的错误:

ORA-01031:insufficient privileges

但奇怪的是,同样的语句,在SQL窗口执行正常。

这种现象的原因,涉及到Oracle对用户权限的处理,在Oracle中用户的权限分为三类:
1. 系统权限:对于数据库某一类对象的权限,如创建表、更改表等操作,具体的权限清单可以在SYSTEM_PRIVILEGE_MAP表中查询到。
说明:权限的名称中如含有ANY,表示权限不限当前的Schema。
2. 对象权限:对于特定数据库对象(如表、视图、、触发器、函数、存储过程等)的权限(如SELECT、INSERT、UPDATE、DELETE等),授权方式为:

GRANT SELECT ON TABLE TO USERA;

3. 角色权限:用户的系统权限和对象权限都是直接赋予用户的,为了简化权限的管理,可以把相同的权限赋予某个角色,然后把角色赋予用户,这样用户就间接的拥有了角色的权限。Oracle默认已经设置了几个角色,常用的是CONNECT、RESOURCE、DBA等。

调用存储过程中的权限机制,根据网上的资料分析总结,在存储过程的内部,用户所具有的权限是存储过程的Owner的系统权限和对象权限,不包括角色权限
在最前面所说的问题,就是用户创建表的权限是在角色权限中,所以在SQL窗口中可以执行,但在存储过程中无法执行。

处理方法:
1. 在存储过程的声明语句增加AUTHID CURRENT_USER语句,Oracle判断存储过程权限变为调用者的所有权限,不再是存储过程Owner的权限。
2. 给用户增加CREATE TABLE的系统权限

权限相关的表:
用户拥有的系统权限 USER_SYS_PRIVS
用户拥有的对象权限 USER_TAB_PRIVS
用户拥有的角色 USER_ROLE_PRIVS

系统内的角色 DBA_ROLES
角色拥有的系统权限 ROLE_SYS_PRIVS
角色拥有的角色权限 ROLE_TAB_PRIVS

权限清单 SYSTEM_PRIVILEGE_MAP

参考资料:
Oracle 用户、对象权限、系统权限

Comments are closed.