本地用户必须在PDB中创建,不能在CDB$ROOT执行;否则报ORA-65096错误。正确流程:先SHOW CON_NAME确认容器,再ALTER SESSION SET CONTAINER=XEPDB1切换,然后CREATE USER app_user IDENTIFIED BY pwd DEFAULT TABLESPACE users QUOTA UNLIMITED ON users,最后GRANT CREATE SESSION, CREATE TABLE TO app_user。
本地用户必须在PDB中创建,不能在CDB$ROOT里执行
直接在cdb$root中运行create user app_user identified by pwd会报ora-65096: invalid common user or role name——oracle把没带c##前缀的用户名默认当成common user处理,而cdb$root不允许创建local user。
正确做法是先确认当前容器:SHOW CON_NAME,如果不是目标PDB(比如XEPDB1),必须先切换:ALTER SESSION SET CONTAINER = XEPDB1。只有在这个上下文中,CREATE USER才创建local user。
- 常见错误:用
sqlplus / as sysdba登录,默认进CDB$ROOT,忘了切容器就建用户 - 验证是否成功:在PDB中查
SELECT USERNAME FROM DBA_USERS WHERE USERNAME = 'APP_USER',如果查不到,大概率还在CDB$ROOT里操作 - XE版默认PDB名是
XEPDB1,不是ORCLPDB或PDB1,别凭经验硬写
给本地用户授基本权限时,CONTAINER=CURRENT是默认且唯一有效方式
GRANT CREATE SESSION, CREATE TABLE TO app_user这类语句在PDB中执行时,CONTAINER=CURRENT是隐式生效的,显式加上也行,但加CONTAINER=ALL会直接报错ORA-65048——因为CONTAINER=ALL只对common user有效,local user根本不认这个参数。
权限只作用于当前PDB,不会同步到其他PDB,这是local user的设计原则。想让同名用户在多个PDB都有权限,必须逐个PDB执行授权,或者写脚本循环切换容器再GRANT。
- 别指望
GRANT ... CONTAINER=ALL能批量搞定多个PDB的local user——语法不支持,会失败 - 常用最小权限组合:
CREATE SESSION(登录)、CREATE TABLE(建表)、UNLIMITED TABLESPACE(避免配额不足) - 如果用户需要查数据字典视图(比如做监控或开发工具),得额外加
SELECT ANY DICTIONARY,但注意这属于高危权限,慎给
表空间配额必须显式指定,否则用户无法建对象
创建本地用户时,如果不指定默认表空间和配额,用户虽然能连上,但一建表就报ORA-01950: no privileges on tablespace 'USERS'。Oracle不会自动给local user分配USERS表空间的无限配额。
正确写法:CREATE USER app_user IDENTIFIED BY pwd DEFAULT TABLESPACE users QUOTA UNLIMITED ON users。如果用了自定义表空间(比如BIGDATA_TS),配额也要对应写在那个表空间上。
- 配额只对默认表空间生效,
QUOTA UNLIMITED ON users不影响其他表空间 - 如果后续要限制空间用量,用
ALTER USER app_user QUOTA 100M ON users,不是GRANT语句 - 查当前配额:
SELECT TABLESPACE_NAME, BYTES/1024/1024 MB FROM DBA_TS_QUOTAS WHERE USERNAME = 'APP_USER'
权限变更后,务必在目标PDB里验证,别只看CDB视图
执行完GRANT后,很多人习惯查DBA_SYS_PRIVS或SESSION_ROLES,但如果是在CDB$ROOT里查,看到的是CDB级权限视图,根本反映不出PDB里的实际状态。必须在目标PDB会话里查才准。
验证步骤:先ALTER SESSION SET CONTAINER = XEPDB1,再运行SELECT * FROM SESSION_ROLES(看角色)、SELECT PRIVILEGE FROM DBA_SYS_PRIVS WHERE GRANTEE = 'APP_USER'(看系统权限)。如果查不到,说明权限没落到这个PDB。
- 常见疏忽:授权后没切回PDB验证,以为成功了,结果应用连上去还是报权限不足
-
DBA_*视图在CDB里默认只显示当前容器数据;想跨容器查要用CDB_*视图,但CDB_SYS_PRIVS里CON_ID字段得手动JOINV$PDBS才能定位到具体PDB - 最简验证法:用新用户直接连
sqlplus app_user/pwd@XEPDB1,然后CREATE TABLE t1(c1 NUMBER)试试
本地用户权限配置的关键不在“怎么赋权”,而在“在哪赋权”——容器上下文错了,一切操作都白忙。最容易被忽略的是:授权语句本身没问题,但执行它的会话容器错了,或者验证它的会话容器也错了。


















