你不能通过修改\_O7\_DICTIONARY\_ACCESSIBILITY撤销用户对DBA视图的查询权限,该参数仅在实例启动时读取、不控制运行时权限,且12.2+已弃用;真正需回收的是SELECT_CATALOG_ROLE等授权。
直接说结论:你不能通过修改 _o7_dictionary_accessibility 来“撤销用户对 dba 视图的查询权限”——这个参数根本不是权限开关,它不控制任何会话级或用户级访问行为,改了也没用。
为什么 ALTER SYSTEM SET _O7_DICTIONARY_ACCESSIBILITY=FALSE 无效
这个参数只在实例启动时读取一次,运行中无法动态修改:ALTER SYSTEM SET _O7_DICTIONARY_ACCESSIBILITY=FALSE 会报错 ORA-02095(指定的初始化参数不可修改)。即使你写进 SPFILE 并重启,它也只影响 CONNECT 角色用户的默认字典可见性,对已授权用户完全无感。
常见误操作包括:
- 在 JDBC URL 里加
?_O7_DICTIONARY_ACCESSIBILITY=false—— 驱动静默忽略,不报错也不生效 - 用
ALTER SESSION或 SQL Hint 尝试设置 —— 语法错误,Oracle 不识别该会话级用法 - 以为设成 FALSE 后,带
SELECT ANY TABLE的用户就查不了DBA_TABLES—— 错,只要他有SELECT_CATALOG_ROLE或显式GRANT SELECT ON SYS.DBA_TABLES,照样能查
真正该回收的是角色和对象授权
DBA 视图(如 DBA_TABLES、DBA_USERS)的访问控制,完全依赖授权体系,不是靠隐藏参数遮掩。
执行以下检查和清理才是有效动作:
- 回收高危角色:
REVOKE SELECT_CATALOG_ROLE FROM app_user; - 检查是否被直接授权:
SELECT * FROM DBA_TAB_PRIVS WHERE GRANTEE = 'APP_USER' AND TABLE_NAME LIKE 'DBA%'; - 逐条回收显式授权:
REVOKE SELECT ON SYS.DBA_TABLES FROM app_user; - 确认无残留系统权限:
SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE = 'APP_USER' AND PRIVILEGE LIKE '%DICTIONARY%';(重点查SELECT ANY DICTIONARY)
O7_DICTIONARY_ACCESSIBILITY 在 RAC 和 PDB 中的行为差异
这个参数在多租户和集群环境下更易出错:
- 在 PDB 中可单独设置(
ALTER PLUGGABLE DATABASE ... SET PARAMETER),但仅影响该 PDB 启动时行为,不跨容器生效 - 在 RAC 中若实例数 > 2,
_O7_DICTIONARY_ACCESSIBILITY的主备控制逻辑失效,文档明确标注“not applicable” - 12.2+ 版本已标记为 deprecated,MOS 文档 ID 206795.1 明确建议“不要更改”,未来版本可能移除
最常被忽略的一点:哪怕你把 _O7_DICTIONARY_ACCESSIBILITY 设为 TRUE,只要没给用户 SELECT_CATALOG_ROLE 或显式授权,他依然查不到 DBA_*;反过来,哪怕设为 FALSE,只要授权存在,视图照查不误。权限不在参数里,在 DBA_ROLE_PRIVS 和 DBA_TAB_PRIVS 里。


















