必须先切换到目标pdb容器再创建无c##前缀用户,否则报ora-65096(在cdb$root建普通名)或ora-65094(在pdb建c##名);确认当前容器用show con_name或select sys_context('userenv','con_name') from dual,非目标pdb需执行alter session set container=your_pdb_name。

C##前缀的用户名执行CREATE USER,否则会报ORA-65096或ORA-65094。
怎么确认当前会话在目标PDB里
连上数据库后,默认在CDB$ROOT,不是PDB。不确认就建用户,十有八九建错地方。
- 运行
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL,返回值必须是你的PDB名(比如HRPDB),不能是CDB$ROOT或PDB$SEED - 或者更简单:
SHOW CON_NAME,看输出是否为你想操作的PDB - 如果不对,立刻执行
ALTER SESSION SET CONTAINER = your_pdb_name;推荐连接时直接指定服务名:sqlplus /@hrpdb,省得切错
为什么CREATE USER test IDENTIFIED BY test会报ORA-65094
这个错误说明你正在PDB里,但用了C##前缀——PDB不允许创建公共用户,语法校验直接拦截。
-
C##test、c##test、MY_PREFIXtest(哪怕你改过common_user_prefix)在PDB里都非法 - 本地用户命名规则和11g完全一致:字母开头、只含字母数字下划线、不保留字即可
- 只要用户名不含
C##(或你自定义的前缀),且不与当前PDB中已存在的公共用户同名,就能通过
建完用户后权限为什么连不上
常见错觉是“建完用户就该能登录”,其实缺了最基础的CREATE SESSION权限。
- 必须在同一个PDB里执行授权:
GRANT CREATE SESSION TO hr,不能跑到CDB$ROOT去授 - 别用
GRANT DBA TO hr——DBA角色在PDB中不存在,会报ORA-01917 - 如果要用
RESOURCE这类预定义角色,它在PDB中可用,但只映射本PDB权限,不影响其他容器 - 密码过期、账户锁定等常规问题仍存在,查
DBA_USERS里的ACCOUNT_STATUS字段
删用户时容易误删整个CDB的同名用户
这是最危险的操作盲区:在CDB$ROOT执行DROP USER hr CASCADE,Oracle 12.2+默认会连同所有PDB里的hr本地用户一起删掉。
- 务必先确认容器:
SHOW CON_NAME必须是目标PDB名 - 删除前检查:
SELECT USERNAME, CON_ID FROM CDB_USERS WHERE USERNAME = 'HR',看CON_ID是否只对应当前PDB - 安全做法:始终在PDB内执行
DROP USER hr CASCADE,而不是切回根容器操作











