session_roles仅显示当前启用的角色,不反映授予来源;需结合dba_role_privs(直授)、role_role_privs(递归查继承链)及user_role_privs(普通用户)综合分析角色授予路径与启用状态。
直接查 session_roles 只能看到当前已启用的角色,看不到继承链;要看到“谁给了你这个角色”,得从数据字典里挖三层关系。
查当前会话启用的角色(最常用)
这是最快的方式,但仅反映 SET ROLE 后生效的角色,不体现授予来源:
SELECT * FROM SESSION_ROLES;
注意:如果没执行过 SET ROLE,且用户没默认角色(DEFAULT ROLE 被禁用),这里可能为空——不是没角色,而是没启用。
查当前用户直接被授予的角色(不含间接继承)
用 DBA_ROLE_PRIVS(需 DBA 权限)或 ROLE_ROLE_PRIVS(更关键)反向追溯:
-
DBA_ROLE_PRIVS查的是“谁把哪些角色授给了你”:SELECT GRANTED_ROLE, ADMIN_OPTION, DEFAULT_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE = SYS_CONTEXT('USERENV', 'CURRENT_USER'); - 但若 A→B→你,这条查不到 A;真正要挖继承链,得靠
ROLE_ROLE_PRIVS
查角色的嵌套继承关系(关键难点)
ROLE_ROLE_PRIVS 记录了“角色能授予其他角色”,它是构建继承图谱的核心表。递归查询才能看清链条:
SELECT LEVEL, GRANTED_ROLE, GRANTEE
FROM ROLE_ROLE_PRIVS
START WITH GRANTEE IN (
SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS
WHERE GRANTEE = SYS_CONTEXT('USERENV', 'CURRENT_USER')
)
CONNECT BY PRIOR GRANTED_ROLE = GRANTEE;
常见坑:
- 结果里
GRANTEE是“被授角色者”,GRANTED_ROLE是“被授予的角色”——方向容易看反 - Oracle 默认不展开无限循环,但若存在角色自授(如 A 授予 A),会报
ORA-01436: CONNECT BY loop - 普通用户查
DBA_ROLE_PRIVS会提示权限不足,此时应改用USER_ROLE_PRIVS(只查自己直接受授的角色)
组合查询:带角色启用状态 + 继承路径
实际排查权限问题时,光知道“有角色”不够,还得知道它是否在当前会话生效:
- 先确认哪些角色已启用:
SESSION_ROLES - 再查这些角色是从哪来的:
SELECT * FROM ROLE_ROLE_PRIVS逐层向上找 - 特别注意
ADMIN_OPTION和DELEGATE OPTION(12c+)——决定你能否继续转授该角色 - 如果角色含对象权限(比如
SELECT ANY TABLE),还要关联ROLE_TAB_PRIVS或ROLE_SYS_PRIVS看具体能力
角色继承不是树状而是有向图,一个角色可能被多个上级授予,路径可能分叉;人工肉眼梳理超过 3 层就容易漏,建议导出结果后用文本工具折叠查看层级。











