SESSION_ROLES为空导致ORA-01031,根本原因是PL/SQL运行时仅识别已激活角色权限,而未启用的角色权限在存储过程中完全失效;必须通过SET ROLE显式激活角色,或检查默认表空间与配额。
为什么 SESSION_ROLES 为空会导致存储过程报 ORA-01031
调用者明明被授予了 dba 角色,但过程一运行就崩,根本原因不是权限没给,而是角色根本没激活。oracle 在 pl/sql 运行时只认 session_roles 里列出的角色权限,这个视图为空,等于所有角色权限全部失效。
常见现象:
- SQL*Plus 里手动执行
SELECT * FROM hr.employees成功,但同一语句放进存储过程就报ORA-00942 - 用户有
CREATE TABLE权限(来自 RESOURCE 角色),但过程里EXECUTE IMMEDIATE 'CREATE TABLE t1(id INT)'报ORA-01031 - 连接工具(如 SQL Developer、JDBC)默认不启用角色,而你在 SQL*Plus 测试时用了
SET ROLE ALL却没意识到环境差异
怎么确认角色是否真在当前会话生效
别查 DBA_ROLE_PRIVS,那只是“你被授过哪些角色”,不是“你现在能用哪些”。必须查运行时上下文:
- 登录后立即执行:
SELECT * FROM SESSION_ROLES;—— 如果返回空集,说明角色全未启用 - 再执行:
SELECT * FROM SESSION_PRIVS;—— 这里只显示直接授予的系统权限,不含角色带来的权限 - 若角色带密码,需显式激活:
SET ROLE role_name IDENTIFIED BY password; - 若想一次性启用所有可启用角色:
SET ROLE ALL;(前提是这些角色没设密码)
AUTHID CURRENT_USER 模式下仍失败的三个关键检查点
改了 AUTHID CURRENT_USER 还不行,大概率卡在这三处:
- 调用者会话里
SESSION_ROLES为空 → 先SET ROLE,不是改过程就能绕过 - 角色里缺对应权限 → 比如想建表,
RESOURCE含CREATE TABLE,但CONNECT不含;想查DBA_USERS,得有SELECT_CATALOG_ROLE或显式GRANT SELECT ON sys.dba_users TO user - 目标对象跨 schema 且权限粒度太粗 →
SELECT ANY TABLE可行,但若只给了SELECT ON hr.employees,过程里却查scott.emp,照样ORA-00942
默认表空间缺失也会伪装成权限错误
过程里执行 CREATE TABLE 报 ORA-01031,有时根本不是权限问题,而是用户没配默认表空间或没配额:
- 检查:
SELECT username, default_tablespace, temporary_tablespace FROM dba_users WHERE username = 'YOUR_USER'; - 若
default_tablespace是空或SYSTEM,且没配额,建表会失败 - 修复:
ALTER USER your_user DEFAULT TABLESPACE users;+ALTER USER your_user QUOTA UNLIMITED ON users; - 注意:这条命令必须由 DBA 执行,且
users表空间得真实存在并在线
实际排查时,先跑 SELECT * FROM SESSION_ROLES;,再看 SESSION_PRIVS,最后确认表空间——三步下来,90% 的“权限不足”都能定位到真实瓶颈,而不是在 GRANT 和 AUTHID 之间反复横跳。


















