查用户对象权限应优先用DBA_TAB_PRIVS查对象级权限,仅需确认列级权限时才查DBA_COL_PRIVS;二者需UNION ALL联合查询并字段对齐,且须同步排查角色权限、系统权限及对象属主身份。
查用户对象权限该用 DBA_TAB_PRIVS 还是 DBA_COL_PRIVS
看权限粒度:dba_tab_privs 查的是表、视图、序列等对象级权限(比如 select 整张表),dba_col_privs 查的是列级权限(比如只对 salary 列有 update 权限)。多数时候先查 dba_tab_privs,只有明确需要确认某列是否被单独授权时才查后者。
常见错误现象:用 DBA_TAB_PRIVS 查不到某用户能改某列的权限,就以为没授权——其实权限可能落在 DBA_COL_PRIVS 里。
-
GRANT UPDATE(salary) ON emp TO alice这种写法只会出现在DBA_COL_PRIVS,DBA_TAB_PRIVS里完全不记录 - 两个视图都要求
SELECT_CATALOG_ROLE或 DBA 权限,普通用户默认查不到 -
DBA_TAB_PRIVS的GRANTABLE字段为YES表示可再转授,这个字段在DBA_COL_PRIVS里不存在
怎么快速定位某个用户对某张表的全部权限
别分开查两个视图再手动合并,直接 UNION ALL 联合查询更可靠。关键是要对齐字段,尤其是列级权限要补上 NULL 占位,否则 ORDER BY 会出错。
实操建议:
- 用
GRANTEE筛选用户名(注意大小写,Oracle 默认大写) - 用
OWNER和TABLE_NAME定位对象,不要只靠TABLE_NAME(不同 schema 可能有同名表) - 列级权限的
COLUMN_NAME在DBA_TAB_PRIVS中为空,必须用NULL AS COLUMN_NAME对齐
SELECT 'TABLE' AS TYPE, OWNER, TABLE_NAME, PRIVILEGE, GRANTABLE, NULL AS COLUMN_NAME FROM DBA_TAB_PRIVS WHERE GRANTEE = 'ALICE' AND OWNER = 'SCOTT' AND TABLE_NAME = 'EMP' UNION ALL SELECT 'COLUMN' AS TYPE, OWNER, TABLE_NAME, PRIVILEGE, NULL AS GRANTABLE, COLUMN_NAME FROM DBA_COL_PRIVS WHERE GRANTEE = 'ALICE' AND OWNER = 'SCOTT' AND TABLE_NAME = 'EMP' ORDER BY TYPE, COLUMN_NAME;
DBA_TAB_PRIVS 里 GRANTOR 是谁?为什么有时是 SYS
GRANTOR 是实际执行 GRANT 命令的用户。但如果是通过角色间接获得权限(比如 SELECT_CATALOG_ROLE 包含 SELECT 某些数据字典表的权限),GRANTOR 就显示为 SYS——这不是 bug,而是 Oracle 内部机制:系统角色的权限由 SYS 隐式授予。
容易踩的坑:
- 看到
GRANTOR = 'SYS'就以为是 DBA 手动授的权,其实可能是角色继承来的,得去查ROLE_TAB_PRIVS -
DBA_TAB_PRIVS不包含通过角色获得的权限,只显示直接授予对象的权限;角色权限得查ROLE_TAB_PRIVS或SESSION_PRIVS - 如果用户有
DBA角色,DBA_TAB_PRIVS会暴露出大量系统对象权限,干扰判断,查前先确认是否真需要这些
权限查询结果为空,但用户确实能操作对象,问题出在哪
最常忽略的三个方向:角色权限、系统权限、对象属主身份。
- 用户可能通过角色获得权限,但
DBA_TAB_PRIVS不体现角色路径,得查DBA_ROLE_PRIVS→ROLE_TAB_PRIVS追溯 - 像
SELECT ANY TABLE这类系统权限,不会出现在DBA_TAB_PRIVS,要查DBA_SYS_PRIVS - 如果用户就是表的
OWNER,无需显式授权就能操作(除了某些限制场景如DEFINER'S RIGHTS过程),这时DBA_TAB_PRIVS自然为空
查之前先问一句:这个用户是不是对象所有者?有没有启用角色?有没有系统权限?别一上来就盯着 DBA_TAB_PRIVS 死磕。










