查系统权限不必须用DBA_SYS_PRIVS;普通用户应使用USER_SYS_PRIVS自查直接权限,SESSION_PRIVS可查会话实际生效权限(含角色继承),DBA_SYS_PRIVS仅限DBA或授权用户查询任意用户权限。
查系统权限必须用 DBA_SYS_PRIVS 吗?
不是必须,但要看你身份和需求。如果你是普通用户,dba_sys_privs 查不到任何结果——它需要 dba 权限(或 select_catalog_role 等显式授权),否则直接报 ora-00942: table or view does not exist。这时候该切到 user_sys_privs,它只返回当前用户「直接拥有」的系统权限,比如 create session、create table,不依赖角色,也不需要额外权限。
-
DBA_SYS_PRIVS:适合 DBA 或有授权的运维人员,查任意用户(如WHERE grantee = 'SCOTT') -
USER_SYS_PRIVS:普通开发/应用账号自查,安全、轻量、无需权限 -
SESSION_PRIVS:更实用——它返回当前会话「实际生效」的所有系统权限,含通过角色间接获得的,比如你被授予了CONNECT角色,SESSION_PRIVS就会列出CREATE SESSION,而USER_SYS_PRIVS不会
DBA_SYS_PRIVS 里 ADMIN_OPTION 是干啥的?
它决定你能不能把权限「再转授」给别人。值为 YES 表示你不仅能自己用这个权限,还能用 GRANT ... WITH ADMIN OPTION 把它授予别人;NO 就只能自用。常见误区是以为 ADMIN_OPTION = YES 就等于有 DBA 权限——其实不是,比如 CREATE USER 带 ADMIN OPTION,你确实能建用户,但建出来的用户默认没 CREATE SESSION,连登录都不行,得手动补。
- 查自己有没有带管理权的权限:
SELECT privilege FROM DBA_SYS_PRIVS WHERE grantee = USER AND admin_option = 'YES' - 注意:即使你有
GRANT ANY PRIVILEGE,也不代表能绕过对象权限校验,它只管系统权限的授予动作 - 生产环境慎用
WITH ADMIN OPTION,权限容易扩散失控,审计时难追溯
为什么查不到通过角色继承的系统权限?
DBA_SYS_PRIVS 只存「直接授予」的记录,角色里的权限藏在 ROLE_SYS_PRIVS 里,而角色到用户的映射在 DBA_ROLE_PRIVS 中。三者要连查才能拼出完整视图。比如用户 APP_USER 被授了 RESOURCE 角色,而 RESOURCE 包含 CREATE TABLE,那这条权限不会出现在 DBA_SYS_PRIVS 的 grantee = 'APP_USER' 结果里。
- 快速查某用户所有系统权限(含角色继承):
SELECT privilege FROM DBA_SYS_PRIVS WHERE grantee = 'APP_USER' UNION SELECT b.privilege FROM DBA_ROLE_PRIVS a JOIN ROLE_SYS_PRIVS b ON a.granted_role = b.role WHERE a.grantee = 'APP_USER' - 别漏掉
DEFAULT ROLE状态——如果角色没被设为默认(ALTER USER ... DEFAULT ROLE),即使已授予,也不会在会话中激活,SESSION_PRIVS也查不到 - Oracle 12c+ 支持公共角色(common roles),跨 PDB 查询时要注意容器上下文,
CURRENT_CONTAINER和CON_ID字段得带上
查权限时最容易忽略的两个点
一是大小写敏感问题:grantee 字段存的是大写用户名(除非建用户时加了双引号),所以 WHERE grantee = 'scott' 查不到,必须写 'SCOTT';二是权限可能被回收但未级联——比如你收回了用户 A 的 DBA 角色,但 A 已经用它授予别人权限,那些「子权限」不会自动消失,得单独清理。
- 安全起见,查前先确认用户名:
SELECT username FROM DBA_USERS WHERE UPPER(username) = UPPER('your_user') - 回收权限时加
CASCADE CONSTRAINTS或手动扫DBA_TAB_PRIVS/DBA_SYS_PRIVS,避免残留 -
DBA_SYS_PRIVS不包含SYSDBA/SYSOPER这类管理权限,那是V$PWFILE_USERS管的,别混用










