Oracle 18c 不支持 SCHEMA 级权限,GRANT SELECT ANY TABLE ON SCHEMA HR TO user 语法非法,会报 ORA-00905;可行方案是用 PL/SQL 动态批量授予 HR 下所有表、视图、序列等对象的 SELECT 权限,并显式处理同义词依赖。

Oracle 18c 不支持 SCHEMA 级权限——这个功能是 23c 才引入的,18c 中根本不存在 GRANT SELECT ANY TABLE ON SCHEMA HR TO user 这类语法,强行执行会报 ORA-00905: missing keyword。
为什么在 18c 里搜“SCHEMA 权限”总踩坑
不少 DBA 或开发看到 23c 文档后反向套用到 18c 环境,结果语句执行失败却以为是写法不对。实际上,18c 的权限模型里没有 ON SCHEMA 这个子句,所有对象权限必须落到具体对象(表、视图等)或使用系统级权限(如 SELECT ANY TABLE)。
-
GRANT SELECT ON HR.EMPLOYEES TO user_a✅ 合法,但要一张张写 -
GRANT SELECT ANY TABLE TO user_a✅ 合法,但太宽泛,含高危风险 -
GRANT SELECT ANY TABLE ON SCHEMA HR TO user_a❌ 18c 解析失败,ON SCHEMA是无效关键词
18c 中真正可行的“类 SCHEMA 级”授权方案
虽然不能按 schema 批量授权,但可通过 PL/SQL 动态生成语句,逼近“一次配置、覆盖全 schema”的效果。关键点在于:必须以 schema owner 或 DBA 身份执行,且只作用于当前已存在的对象。
- 先确认目标 schema 下有哪些普通表:
SELECT table_name FROM dba_tables WHERE owner = 'HR' AND temporary = 'N' - 用匿名块批量生成并执行授权语句(以 HR 用户或 DBA 身份运行):
DECLARE CURSOR c IS SELECT table_name FROM dba_tables WHERE owner = 'HR' AND temporary = 'N'; BEGIN FOR r IN c LOOP EXECUTE IMMEDIATE 'GRANT SELECT ON HR.' || r.table_name || ' TO app_reader'; END LOOP; END; - 注意:该方式不自动覆盖新表,后续新增表需重新跑脚本或加入部署流程
别漏掉序列、视图、同义词这些“隐形依赖”
只授了表的 SELECT 权限,应用仍可能报错,因为真实业务常依赖其他对象:
- 序列(
SEQUENCE):如果代码里有HR.seq_id.NEXTVAL,需额外授SELECT权限:GRANT SELECT ON HR.seq_id TO app_reader - 视图(
VIEW):即使底层表已授权,视图本身也要单独授SELECT,否则SELECT * FROM HR.vw_emp会报ORA-00942 - 同义词(
SYNONYM):同义词只是别名,权限检查仍走原对象,但若同义词指向另一 schema 的表,就得去那个 schema 授权,不是在当前 schema 操作
18c 没有语法糖,所谓“简化”本质是靠脚本封装 + 显式枚举。最容易被跳过的不是表,而是序列和视图——它们不出现在 dba_tables 里,但一出错就卡住整个查询链。


















