ORA-65096错误源于CDB/PDB架构限制,非命名校验bug;在CDB$ROOT中创建用户必须以c##开头,或切至PDB建本地用户,或临时启用\_oracle\_script参数(有风险)。
ORA-65096 错误本质是容器架构限制,不是命名校验bug
oracle 12c 引入多租户(cdb/pdb)后,create user 默认在 cdb$root 容器执行,此时只能创建「公用用户」,而 oracle 强制要求公用用户名必须以 c## 或 c## 开头。这不是语法错误,是架构级约束——你没切容器,系统就按 cdb 规则校验名称。
直接改 _oracle_script 隐藏参数能绕过校验,但有明确风险
在 CDB$ROOT 中执行:
ALTER SESSION SET "_oracle_script" = TRUE;之后再运行
create user test identified by test; 就不会报 ORA-65096。这个参数本质是让 Oracle 暂时降级为“类 11g 模式”处理用户创建,跳过公用用户前缀检查。
但要注意:
-
_oracle_script是未公开的隐藏参数,官方不承诺兼容性,升级或打补丁后可能失效 - 它只对当前 session 生效,不能写进 pfile/spfile 全局启用
- 创建的用户仍是公用用户(出现在所有 PDB),只是名字没加
c##,权限模型没变 - 某些 DBA 工具或备份脚本依赖标准命名规范,可能出问题
更稳妥的做法:先切到 PDB 再创建本地用户
绝大多数应用不需要公用用户。你应该把用户建在业务对应的 PDB 里,这才是 Oracle 12c 推荐模式。
操作步骤:
- 确认目标 PDB 名称:
SHOW PDBS - 检查 PDB 是否已打开:
SELECT NAME, OPEN_MODE FROM V$PDBS WHERE NAME = 'YOUR_PDB';,若为MOUNTED则需先ALTER PLUGGABLE DATABASE YOUR_PDB OPEN; - 切换容器:
ALTER SESSION SET CONTAINER = YOUR_PDB; - 创建用户(无需
c##):CREATE USER app_user IDENTIFIED BY pwd DEFAULT TABLESPACE users; - 授权:
GRANT CREATE SESSION, RESOURCE TO app_user;
这样创建的是本地用户,只存在于该 PDB,名字干净,权限隔离,且完全符合 Oracle 设计意图。
用 c## 前缀创建公用用户时的真实约束
如果你确实需要跨 PDB 共享的用户(比如监控账号、DBA 工具账号),必须用 c## 前缀,但要注意:
- 用户名在数据字典中存储为小写,
c##Test实际存为c##test,大小写不敏感 - 该用户默认无法登录 PDB,除非显式授予
SET CONTAINER权限:GRANT SET CONTAINER TO c##admin; - 不能在 PDB 中给公用用户分配本地对象权限(如
GRANT SELECT ON pdb_table TO c##admin;),会报 ORA-65048 - 删除时也必须在 CDB$ROOT 执行:
DROP USER c##admin CASCADE;
真正容易被忽略的是:即使你用了 c##,如果 PDB 没 open,或者表空间不存在,CREATE USER 仍会失败——ORA-65096 只是第一个拦路虎,后面还有更实际的依赖要处理。











