ora-01950本质是目标表空间配额缺失或为零,需用dba账号查dba_ts_quotas确认;空记录或max_bytes=0即无配额,应执行alter user quota on指定表空间授权,禁用unlimited tablespace。

查 DBA_TS_QUOTAS 确认配额是否存在或为零
ORA-01950 的本质不是缺权限,而是用户在目标表空间没配额,或者配额被设为 0。必须用 DBA 账号(如 SYS 或 SYSTEM)查 DBA_TS_QUOTAS,普通用户查 USER_TS_QUOTAS 只能看到自己,容易漏掉问题。
执行这条语句,把 'USER1' 换成实际报错的用户名,'USERS' 换成错误信息里写的表空间名:
SELECT tablespace_name, max_bytes FROM dba_ts_quotas WHERE username = 'USER1' AND tablespace_name = 'USERS';
结果含义很直接:
- 空行 → 完全没配额
-
max_bytes = 0→ 配额被显式设为零(等同于禁用) -
max_bytes = -1→UNLIMITED已生效 - 正数(如
10737418240)→ 有配额,但可能已耗尽
确认报错时实际使用的表空间名
错误信息里写的表空间名(比如 'K3CLOUD_DATA'、'TBS1')就是真实目标,别默认只盯 USERS。它不一定等于用户的默认表空间。
常见来源包括:
- 对象创建时显式指定:
CREATE TABLE t1 (...) TABLESPACE K3CLOUD_DATA - 索引属主不同:用户
USER1的表T1上,USER2创建了索引并指定TABLESPACE TBS1→ 报错是USER2在TBS1没配额 - 迁移工具硬编码:Data Pump 的
remap_tablespace参数,或应用配置里写了固定表空间
查索引归属的语句:
SELECT owner, tablespace_name FROM dba_indexes WHERE table_owner = 'USER1' AND table_name = 'T1';
然后对查出的 owner(不是 table_owner)去配额。
用 ALTER USER ... QUOTA 授权,别碰 UNLIMITED TABLESPACE
GRANT UNLIMITED TABLESPACE TO user 能绕过 ORA-01950,但它允许用户往 SYSTEM、SYSAUX 这类核心表空间写数据,生产环境审计通不过,也容易引发事故。
安全做法是精准控制:
-
ALTER USER USER1 QUOTA UNLIMITED ON USERS;—— 最常用,max_bytes写入 -1 -
ALTER USER USER1 QUOTA 50G ON K3CLOUD_DATA;—— 单位支持K、M、G,按实际预估 -
ALTER USER USER1 QUOTA 0 ON USERS;—— 会从DBA_TS_QUOTAS中删掉该记录,不是“设为零”,而是彻底移除配额
注意:语句必须由 SYS 或 SYSTEM 执行,普通用户无法修改自己或其他人的配额。
跨用户场景下,配额要分人配,不能假设“给了 A 就等于给了 B”
典型误判场景:
-
USER1的表T1上,USER2创建索引 → 报错是USER2在索引所在表空间没配额,和USER1无关 - Data Pump 以
IMP_USER身份导入,但目标表定义落在SCHEMA_OWNER的默认表空间 → 需同时检查两个用户在该表空间的DBA_TS_QUOTAS记录
配额是按 username + tablespace_name 组合绑定的,每个组合都要单独确认。最容易被忽略的一点是:它不继承角色、不共享用户、也不随默认表空间自动生效。











