ora-01950 根本原因是用户在目标表空间无有效配额(max_bytes=0或记录为空),而非权限缺失;需用alter user quota显式授予配额,且配额检查在sql解析阶段即触发。

ORA-01950 不是权限缺失,而是配额为零或未设置
报 ORA-01950: no privileges on tablespace 'USERS' 时,用户很可能已有 CREATE TABLE、CONNECT、RESOURCE 全套权限,甚至被授予了 UNLIMITED TABLESPACE ——但只要在 USERS 表空间上查不到有效配额记录,建表就必然失败。Oracle 在分配段(segment)前只做一件事:查 DBA_TS_QUOTAS 或 USER_TS_QUOTAS,确认该用户在目标表空间的 max_bytes 是否 ≥ 当前操作所需空间。
-
max_bytes = -1:无限制,OK -
max_bytes > 0:单位字节,比如52428800= 50MB;若当前已用bytes >= max_bytes,立即拒绝 -
max_bytes = 0:显式禁止写入,任何 DDL/DML 都失败 - 查询结果为空行:代表该用户在该表空间**完全没被授予配额**,等效于
max_bytes = 0
为什么新建用户常在 USERS 上卡住?
很多 DBA 创建用户时只写:CREATE USER scott IDENTIFIED BY tiger DEFAULT TABLESPACE USERS;,却漏掉 QUOTA 子句。Oracle 不会自动给默认表空间配额度——哪怕 USERS 数据文件还有 100GB 空闲,只要 scott 在它上面没配额,CREATE TABLE t1 (x INT) 就会直接报 ORA-01950。
- 检查语句必须带用户名全大写(除非用双引号建库):
SELECT tablespace_name, max_bytes FROM dba_ts_quotas WHERE username = 'SCOTT' AND tablespace_name = 'USERS'; - 如果返回空,说明压根没配;如果
max_bytes是 0,说明被禁用了 - 别依赖“默认表空间”推断配额存在——默认只影响
TABLESPACE未显式指定时的落盘位置,不等于授权
ALTER USER QUOTA 的常见写法与陷阱
配额必须由 SYS、SYSTEM 或具备 ALTER USER 权限的账号执行,普通用户自己运行该语句会静默失败。
- 正确语法(单位必须大写且紧贴数字):
ALTER USER scott QUOTA 200M ON USERS;,200MB或200都非法 - 表空间名大小写敏感:若
dba_tablespaces中显示为users(小写),而你写ON USERS,在区分大小写的库中会失效 -
QUOTA UNLIMITED ON USERS是最常用解法,但它只放开这一个表空间,比GRANT UNLIMITED TABLESPACE TO scott更细粒度、更安全 - 如果用户建表时显式写了
TABLESPACE EXAMPLE,那你得给EXAMPLE配额,不是USERS
为什么刚加完配额还是报错?
配额修改立即生效,但某些场景下旧事务仍按旧限额检查:
- 长事务正在执行中,且已分配接近上限的空间,新配额对它无效,需等其提交或回滚
- 应用连接的是另一个用户(比如你改了
scott,但程序连的是app_user),务必用SELECT USER FROM DUAL;确认当前会话身份 - 索引或 LOB 段可能落在独立表空间(如
TBS_IDX、TBS_LOB),建表成功不代表后续CREATE INDEX或INSERT大字段就一定成功 - 触发器、物化视图日志、审计表等隐式对象也可能写入非默认表空间,需结合实际 DDL 日志排查











