ORA-01031报错首要检查CREATE SESSION权限是否显式授予用户,因Oracle 23c已移除其在CONNECT角色中的隐式包含;其次确认连接池配置的用户名对应用户已直授该权限,而非依赖SYS切换。

ORA-01031报错时,先别查授权语句,直接看CREATE SESSION
执行GRANT SELECT ANY TABLE ON SCHEMA HR TO BOB后连不上数据库?90% 的情况不是 Schema 权限没授对,而是用户根本没获得连接资格。CREATE SESSION必须显式授予,Oracle 23c 已移除它在CONNECT角色中的隐式包含。不要依赖旧习惯——GRANT CONNECT TO BOB虽能用,但该角色现在只含CREATE SESSION,不如直授更清晰、更可控。
若用 HikariCP 或其他连接池,确认spring.datasource.username=BOB对应的用户已具备该权限,而不是靠SYS登录后再切换用户。连接失败就查这个,比翻几十行授权语句快得多。
Java 查询返回空或 ORA-00942,三处必须人工核对
Schema 级权限确实自动覆盖新建表,但查不到数据往往卡在非权限环节:
- 确认表真在目标 schema 下:
SELECT owner, object_name FROM all_objects WHERE object_type = 'TABLE' AND object_name = 'EMPLOYEES',别误建在应用用户(如APP_USER)下 - 检查 Java 代码中 SQL 是否显式带 schema 前缀:
SELECT * FROM HR.EMPLOYEES;若只写EMPLOYEES,则依赖当前 session 的默认 schema,而BOB的默认 schema 是BOB,不是HR - 刚授完权就查,可能遇极短缓存延迟(毫秒级),加一句
SELECT 1 FROM DUAL触发会话刷新即可
多 schema 场景下,不能靠 SELECT ANY TABLE 一招打天下
一个应用要读HR和FINANCE两个 schema,必须分拆授权,否则要么越权、要么失效:
- 正确做法:
GRANT SELECT ANY TABLE ON SCHEMA HR TO APP_USER+GRANT SELECT ANY TABLE ON SCHEMA FINANCE TO APP_USER - 绝对禁止:
GRANT SELECT ANY TABLE TO APP_USER——它穿透所有 schema,23c 中已明确不推荐,且违反最小权限原则 - 如果应用需写入,改用细粒度对象级授权(如
GRANT INSERT, UPDATE ON HR.EMPLOYEES TO APP_USER),因为 23c 当前不支持INSERT ANY TABLE ON SCHEMA
表空间配额(QUOTA)和 Schema 权限完全正交,别混为一谈
GRANT SELECT ANY TABLE ON SCHEMA HR TO BOB不会让BOB获得HR在USERS表空间的配额——HR的配额只影响HR自己建对象,和BOB无关。同样,BOB的配额也只管BOB自己建的对象(比如同义词、全局临时表),不管他查谁的表。
常见误操作:以为授了 Schema 权限就能建视图或同义词,结果报ORA-01950: no privileges on tablespace 'USERS'。此时应单独配额:ALTER USER BOB QUOTA 10M ON USERS。注意:配额不传递、不继承、不隐含,哪怕你是 DBA 角色,只要没在目标表空间上被授过QUOTA,就无法建任何持久对象。


















