ORA-00959错误源于DEFAULT TABLESPACE或TEMPORARY TABLESPACE指定的表空间不存在、状态异常(OFFLINE/READ ONLY/TEMPORARY)或数据库级默认值失效;需逐项核查dba_tablespaces、database_properties及CDB/PDB上下文。
CREATE USER 报 ORA-00959:表空间不存在,先查它存不存在
不是脚本写错了,而是 default tablespace 后面写的那个名字,在数据库里压根没建好、或者建了但状态不对。oracle 不会自动创建表空间,也不会容忍拼写差一个字母。
执行这两条语句确认现状:
SELECT tablespace_name, status, contents FROM dba_tablespaces WHERE tablespace_name = 'YOUR_TABLESPACE_NAME';
注意把 YOUR_TABLESPACE_NAME 换成你 CREATE USER 里写的那个名,且必须大写(Oracle 默认大写存储)。
- 如果查不到任何结果 → 表空间根本没创建
- 如果查到但
status是OFFLINE或READ ONLY→ 不满足DEFAULT TABLESPACE要求(必须ONLINE且READ WRITE) - 如果
contents是TEMPORARY→ 不能用作永久表空间,DEFAULT TABLESPACE必须指向永久表空间
DEFAULT TABLESPACE 写对了,还是报错?检查是否被 ALTER DATABASE default tablespace 影响
有些 DBA 为图省事,执行过 ALTER DATABASE DEFAULT TABLESPACE xxx。这会导致后续未显式指定 DEFAULT TABLESPACE 的 CREATE USER 隐式继承该值——但如果那个“默认表空间”本身后来被删了或 offline 了,错误就变成“表空间不存在”,而你脚本里明明没写它。
查当前数据库级默认永久表空间:
SELECT property_value FROM database_properties WHERE property_name = 'DEFAULT_PERMANENT_TABLESPACE';
- 如果返回空,说明没设过全局默认,报错一定来自你脚本里的显式指定
- 如果返回一个表空间名,但该表空间已失效 → 即使你没写
DEFAULT TABLESPACE,Oracle 也会去用它,然后失败 - 不建议依赖这个机制:它会影响所有后续用户,且容易被遗忘
临时表空间 TEMPORARY TABLESPACE 也得存在,别只盯 DEFAULT
TEMPORARY TABLESPACE 看似可选,但省略后 Oracle 会查 DEFAULT_TEMP_TABLESPACE 数据库属性。一旦这个值为空、或指向一个不存在/无效的临时表空间,CREATE USER 同样报 ORA-00959,而且错误信息不会告诉你出问题的是临时表空间。
查当前默认临时表空间:
SELECT property_value FROM database_properties WHERE property_name = 'DEFAULT_TEMP_TABLESPACE';
- 如果返回
SYSTEM→ 违反 Oracle 安全要求,ALTER USER ... TEMPORARY TABLESPACE system会被拒绝,建用户直接失败 - 如果返回的表空间不在
dba_tablespaces列表中 → 就是它导致的ORA-00959 - 生产环境别让多个应用用户共用同一个临时表空间,高并发排序可能卡住
12c/21c 多租户环境下,用户名和表空间命名有额外约束
在容器数据库(CDB)中创建公用用户(common user),用户名必须以 c## 开头,否则报 ORA-65096;但这个错误有时会掩盖真正的表空间问题——因为用户创建失败,后续的表空间授权或验证步骤根本没执行。
- 先确认你连的是 CDB 还是 PDB:
SELECT sys_context('USERENV', 'CON_NAME') FROM DUAL; - 如果是 CDB$ROOT,又想在某个 PDB 里建用户,得先
ALTER SESSION SET CONTAINER = your_pdb_name; - 新建的表空间若只在 PDB 中创建,CDB 层看不到,但
CREATE USER在 CDB 层执行时仍会校验 —— 导致“表空间不存在”假象
最易被忽略的一点:表空间创建后,某些 Oracle 版本(如 12.1)需要重启实例或刷新共享池才能让新表空间被完整识别,尤其在刚初始化完数据库后。别急着重写脚本,先试试 ALTER SYSTEM FLUSH SHARED_POOL; 或重启监听器。


















