当前会话的系统权限需查session_privs视图,它动态反映已激活权限;对象权限需结合dba_tab_privs(直接授权)与dba_role_privs(角色启用状态)推断,默认角色(default_role='yes')通常生效,但非实时精确。
查当前活跃用户有哪些权限:从 v$session 和 session_privs 入手
直接查 v$session 只能看到登录信息(比如 username、osuser、logon_time),它不存权限。真正反映当前会话已激活的权限,得看数据字典视图 session_privs——它是基于当前会话上下文动态生成的,只返回该会话此刻拥有的系统权限(如 create table、select any table)。
执行以下语句即可看到你当前连接所拥有的系统权限:
SELECT * FROM SESSION_PRIVS;
注意:SESSION_PRIVS 不包含对象权限(如对某张表的 SELECT 权限),也不含通过角色间接获得但尚未启用的权限。如果用户有多个角色但只启用了部分(比如用 SET ROLE role1),那只有启用角色里的权限才会出现在 SESSION_PRIVS 中。
查某个活跃用户(非当前会话)的对象权限:关联 V$SESSION + DBA_TAB_PRIVS + DBA_ROLE_PRIVS
想查别人正在连着的会话能操作哪些表?不能只靠 DBA_TAB_PRIVS,因为对象权限可能来自直接授权,也可能来自其启用的角色。而角色是否启用,取决于该会话的 ROLE 状态,这个状态在 V$SESSION 里没有直接字段,得结合 DBA_ROLE_PRIVS 的 DEFAULT_ROLE 和实际启用逻辑来推断。
更稳妥的做法是分两步走:
- 先从
V$SESSION拿出目标用户名(USERNAME)和会话 ID(SID) - 再查该用户被直接授予的对象权限:
SELECT OWNER, TABLE_NAME, PRIVILEGE, GRANTOR FROM DBA_TAB_PRIVS WHERE GRANTEE = '目标用户名';
- 再查该用户拥有的角色(含是否默认启用):
SELECT GRANTED_ROLE, DEFAULT_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE = '目标用户名';
关键点:如果某角色的 DEFAULT_ROLE = 'YES',且用户没显式执行过 SET ROLE NONE,那么该角色通常在会话中处于启用状态,其包含的对象权限也就生效。但 Oracle 不会在运行时实时暴露“当前启用的角色列表”,所以严格意义上,你只能基于默认角色 + 用户行为做合理推断。
DBA_SYS_PRIVS 和 DBA_TAB_PRIVS 查的是授权快照,不是实时权限状态
这两个视图反映的是“谁被授予了什么”,不是“此刻谁能用什么”。例如:
- 用户 A 被授予了角色
ROLE_X,而ROLE_X有DELETE ANY TABLE,但 A 当前会话没启用ROLE_X(比如执行过SET ROLE NONE),那么SESSION_PRIVS里就看不到这个权限,尽管DBA_SYS_PRIVS里能查到 A 通过角色间接获得它 - 同理,
DBA_TAB_PRIVS显示 A 对SCOTT.EMP有UPDATE权限,但如果这张表已被DROP或权限被REVOKE但字典缓存未刷新,视图仍可能短暂显示旧记录(极少见,但 RAC 环境下偶发)
所以别把 DBA_* 视图当成“当前权限清单”,它们更适合做审计或配置核查,而非运行时判断。
快速定位权限来源:用 DBA_ROLE_PRIVS 和 ROLE_TAB_PRIVS 追踪角色嵌套
当发现一个用户能访问某张表,但 DBA_TAB_PRIVS 里查不到直接授权记录,大概率是权限来自角色。这时要顺藤摸瓜:
- 查用户有哪些角色:
SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE = '用户名';
- 对每个角色,查它能访问哪些表:
SELECT ROLE, TABLE_NAME, PRIVILEGE FROM ROLE_TAB_PRIVS WHERE ROLE = '角色名';
- 如果角色还包含其他角色(角色嵌套),继续查:
SELECT GRANTED_ROLE FROM ROLE_ROLE_PRIVS WHERE ROLE = '角色名';
注意:ROLE_TAB_PRIVS 只显示“角色定义时包含的对象权限”,不反映该角色是否被授予给用户、也不反映用户当前是否启用它。嵌套层级深时,手工追踪容易漏,建议写个简单递归查询(用 CONNECT BY)或导出后用脚本梳理。
权限链越长,排查越容易卡在“哪个环节没启用”上。生产环境里,最常被忽略的是 DEFAULT_ROLE 设置和 ALTER USER ... DEFAULT ROLE 的变更未同步到已有会话——老会话不会自动重载角色列表。











