DBA角色不自动包含对象访问权限,仅提供系统管理权限;查数据字典需额外授予SELECT_CATALOG_ROLE或SELECT ANY DICTIONARY,对象访问仍须显式授权。

DBA角色不自动包含对象访问权限
授予 DBA 角色 ≠ 自动获得所有用户下对象的查询/执行权限。Oracle 的 DBA 是系统权限集合,它让你能管理数据库(如 CREATE USER、DROP TABLESPACE),但对其他用户的表、视图、过程等对象,默认仍需显式授权。这是设计使然,不是 bug。
常见被忽略的权限类型:SELECT_CATALOG_ROLE 和 SELECT ANY DICTIONARY
很多人以为 DBA 能查 dba_tables 或 v$session,结果报 ORA-00942: table or view does not exist。这是因为:
-
DBA角色本身不包含SELECT ANY DICTIONARY—— 这才是查数据字典视图(如dba_*、all_*)所需的权限 -
SELECT_CATALOG_ROLE是一个预定义角色,提供对只读数据字典视图的访问,但它 不会 自动授予给DBA,必须手动加 - 注意:
SELECT ANY DICTIONARY权限太宽,生产环境应优先用SELECT_CATALOG_ROLE
验证方式:SELECT * FROM session_privs WHERE privilege LIKE '%DICTIONARY%'; —— 如果没结果,就缺这个。
对象权限未通过 WITH GRANT OPTION 传递
即使 A 用户把 SELECT 权限给了 B,B 也不能直接转授给 C,除非当初是 GRANT SELECT ON t TO b WITH GRANT OPTION;。而 DBA 角色不绕过这条规则。典型现象:
- B 用
DBA角色登录,执行SELECT * FROM a.t;成功 - B 执行
GRANT SELECT ON a.t TO c;报ORA-01031: insufficient privileges
解决方法:要么让 A 重新授权并加 WITH GRANT OPTION,要么由 A 直接授给 C。
当前用户 schema 下对象不存在或同义词未创建
最容易被误判为“权限问题”的其实是对象定位失败。比如:
- 执行
SELECT * FROM emp;报ORA-00942,但emp其实属于scottschema —— 正确写法是scott.emp - 没建私有同义词(
CREATE SYNONYM emp FOR scott.emp;)或公有同义词(需CREATE PUBLIC SYNONYM权限) - 当前用户有
DBA,但连的是 PDB 而非 CDB$ROOT,部分数据字典视图(如CDB_TABLES)在 PDB 中不可见
查对象归属:SELECT owner, object_name FROM all_objects WHERE object_name = 'EMP';
真正麻烦的从来不是“有没有 DBA”,而是“DBA 里到底包了哪些权限”和“你查的对象到底在哪儿、归谁管”。Oracle 的权限体系是分层且显式的,漏掉一层,就会卡在看似不该卡的地方。


















