USER_TAB_PRIVS仅查用户直接获得的对象权限,不含角色继承;DBA_TAB_PRIVS查他人权限需DBA权限且区分大小写;视图权限依赖基表权限,需逐层验证。
查当前用户有哪些对象权限,用 USER_TAB_PRIVS
直接连上数据库、以目标用户身份登录后,执行:select owner, table_name, privilege, grantable from user_tab_privs;
它只返回该用户**被直接授予的**表、视图、序列等对象权限(不含角色继承来的)。grantable 为 yes 表示该权限带 with grant option,能再转授他人。
常见错误:用 all_tab_privs 查自己权限——它会包含“你有权限访问、但不是授给你的”对象(比如你被授了 select any table),干扰判断。
查其他用户被授了哪些对象权限,必须用 DBA_TAB_PRIVS
需要 DBA 或 SELECT_CATALOG_ROLE 权限才能查:SELECT owner, table_name, privilege, grantor, grantable FROM DBA_TAB_PRIVS WHERE grantee = 'SCOTT';
注意大小写:Oracle 默认用户名全大写,'scott' 查不到结果。
关键点:
-
DBA_TAB_PRIVS只记录“谁把什么权限授给了谁”,不反映是否启用、也不管角色链 - 如果权限来自角色(比如
SCOTT有CONNECT角色,而CONNECT包含CREATE SESSION),那这条记录不会出现在这里——那是系统权限,得去DBA_SYS_PRIVS或角色视图里找 - 物化视图权限不在这个视图里,要查
DBA_MVIEW_PRIVS
为什么查到权限却还是不能查表?重点看依赖对象
对象权限不是孤立生效的。典型场景:
你给 user2 授了视图 v_emp 的 SELECT 权限,但 v_emp 定义里查的是 schema_a.emp ——如果 user2 没有对 schema_a.emp 的 SELECT 权限,查询仍报 ORA-00942 或 ORA-01031。
解决办法:
- 先用
SELECT text FROM ALL_VIEWS WHERE owner = 'SCHEMA_A' AND view_name = 'V_EMP';看视图定义 - 人工列出所有被引用的表、函数、同义词
- 逐个确认
user2是否拥有对应对象的必要权限(SELECT、EXECUTE等) - 若底层对象属别人,且对方愿放权,可要求其加
WITH GRANT OPTION后再授权给你
批量查某用户对指定 Schema 下所有对象的权限
比如想确认 APP_USER 对 HR 下所有表有没有 SELECT 权限:SELECT table_name, privilege FROM DBA_TAB_PRIVS WHERE grantee = 'APP_USER' AND owner = 'HR' AND privilege = 'SELECT';
注意:
- 这个查询只返回“显式授予”的记录;即使
APP_USER有SELECT ANY TABLE,也不会列在这里 - 如果
HR下有大量视图,记得补查DBA_TAB_PRIVS中table_name对应的是视图名,而非基表名 - 权限可能通过角色间接获得,此时需结合
DBA_ROLE_PRIVS和角色所含的对象权限递归分析


















