在cdb$root中创建用户必须加c##前缀,否则报ora-65096;正确做法是先alter session set container = your_pdb_name切换至目标pdb,再执行create user(无需前缀)并指定pdb内表空间及服务名登录。

必须先切到目标PDB容器再操作
直接用 sqlplus / as sysdba 登录时,默认连的是 CDB$ROOT,此时创建的用户若不加 C## 前缀会报错,或即使成功也属于CDB级用户(不符合本地用户定义)。关键动作是显式切换容器:
- 查当前容器:
SHOW CON_NAME,确认不是CDB$ROOT - 查可用PDB:
SELECT NAME FROM V$PDBS; - 切换容器:
ALTER SESSION SET CONTAINER = your_pdb_name;(例如ORCLPDB) - 确认生效:
SHOW CON_NAME应返回你的PDB名
漏掉这步是 ORA-01017 最常见原因——用户建在CDB里,却试图用PDB服务名去连。
创建用户时不能指定全局表空间
PDB里的本地用户只能使用本PDB内已存在的表空间。如果在CDB中建了表空间(比如放在 /u01/app/oracle/oradata/CDB1/ 下),而没在当前PDB里创建同名表空间或映射,CREATE USER ... DEFAULT TABLESPACE xxx 会失败,报 ORA-00959: tablespace 'xxx' does not exist。
- 先在PDB内建表空间:
CREATE TABLESPACE app_data DATAFILE '/u01/app/oracle/oradata/CDB1/YOUR_PDB/app_data01.dbf' SIZE 200M AUTOEXTEND ON; - 路径必须指向该PDB专属目录(如含GUID的子路径),或明确配置了
PDB_FILE_NAME_CONVERT - 建用户时引用刚建的表空间:
CREATE USER appuser IDENTIFIED BY pwd123 DEFAULT TABLESPACE app_data TEMPORARY TABLESPACE TEMP;
别复用CDB根容器的 USERS 表空间——它在PDB里不可见,除非你手动在PDB中创建同名表空间并挂载对应数据文件。
授权后仍无法登录?检查连接串是否带PDB服务名
用户建在PDB里,登录时必须显式指定该PDB的服务名,否则Oracle默认走CDB监听,找不到这个本地用户。
- 命令行登录:
sqlplus appuser/pwd123@localhost:1521/YOUR_PDB(注意最后是PDB名,不是CDB名) - SQL Developer等工具:连接配置里“Service name”填PDB名(如
ORCLPDB),不是CDB$ROOT或实例名 - tnsnames.ora 中需有对应条目,且
SERVICE_NAME字段值与PDB名一致(大小写敏感)
用 sqlplus appuser/pwd123 不带地址直接连,几乎必然触发 ORA-01017——它连的是CDB监听的缺省服务,根本没进PDB上下文。
常见权限遗漏点:CREATE SESSION 是硬门槛
只给 CONNECT、RESOURCE 或 DBA 不够。Oracle 19c PDB中,CONNECT 角色默认不含 CREATE SESSION 权限(尤其在非OMF环境或自定义角色时)。
- 最稳妥方式:
GRANT CREATE SESSION TO appuser;单独执行 - 验证权限:
SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE = 'APPUSER' AND PRIVILEGE = 'CREATE SESSION'; - 如果用
GRANT DBA TO appuser,理论上包含该权限,但某些补丁版本存在角色继承延迟,建议显式授予
权限给了但没生效,往往是因为没刷新会话或角色未激活——ALTER USER appuser DEFAULT ROLE ALL; 可强制启用所有已授角色。











