ora-01950 根本原因是用户在目标表空间无有效配额,需用dba账号查dba_ts_quotas确认;insert实际使用的表空间由目标表/索引所在表空间决定,非默认或用户所属表空间。

ORA-01950 不是权限缺失,而是用户在目标表空间没配额——INSERT 失败时,必须查 DBA_TS_QUOTAS 确认该用户在报错表空间(比如 'USERS')是否有有效配额,否则补再多系统权限也没用。
怎么快速定位 INSERT 实际用的是哪个表空间?
报错信息里写的表空间名(如 'USERS')就是真实目标,不是默认表空间,也不是建表用户“应该”用的那个。关键要看数据要写入的对象本身在哪:
- 执行
SELECT table_name, tablespace_name FROM dba_tables WHERE owner = 'USER_A' AND table_name = 'TEST';,确认TEST表实际存储在哪个表空间 - 如果表上有索引且
INSERT触发了索引维护,还要查索引位置:SELECT index_name, tablespace_name FROM dba_indexes WHERE table_owner = 'USER_A' AND table_name = 'TEST'; - 迁移工具或 ORM 框架可能硬编码了表空间(比如 Data Pump 的
remap_tablespace),得翻日志或配置
查配额必须用 DBA 账号,别信 user_ts_quotas
user_ts_quotas 只返回当前登录用户的记录,排查别人问题会漏掉。必须用 SYS 或 SYSTEM 执行:
SELECT tablespace_name, max_bytes FROM dba_ts_quotas WHERE username = 'USER_A' AND tablespace_name = 'USERS';- 返回空行 → 完全没配额
- 返回
max_bytes = 0→ 配额被设为零(等同于禁用) - 返回
max_bytes = -1→UNLIMITED已生效 - 返回正数但接近耗尽 → 插入大对象时仍可能失败,需结合
bytes_used判断
ALTER USER QUOTA 必须由 DBA 执行,普通用户静默失败
语句语法正确但没生效?大概率是用错了账号。注意:
- 普通用户执行
ALTER USER ... QUOTA会静默失败,不报错也不生效 - 必须用
SYS AS SYSDBA或SYSTEM登录后执行 - 配额是按
(username, tablespace_name)组合绑定的,不能假设“给了 A 就等于给了 B” - 示例:给用户
USER_A在USERS表空间加配额:ALTER USER USER_A QUOTA UNLIMITED ON USERS; - 若需限制用量,可用带单位写法:
ALTER USER USER_A QUOTA 5G ON USERS;(支持K/M/G)
临时表空间、SYSTEM 表空间不能乱配
QUOTA 对临时表空间无效,对 SYSTEM 表空间配额也极危险:
- 对
TEMP表空间执行ALTER USER ... QUOTA会直接报ORA-02156: invalid temporary tablespace -
ALTER USER ... QUOTA UNLIMITED ON SYSTEM允许往核心字典表写数据,生产环境审计通不过 -
GRANT UNLIMITED TABLESPACE TO USER_A是全局绕过,不解决单表空间缺失配额的问题,还引入安全风险
最常被忽略的一点:配额检查发生在段分配时刻,不是语句解析时。哪怕 INSERT 语句本身合法,只要执行中需要扩展数据段(比如插入 LOB、触发索引分裂、批量插入触发新 extent 分配),就会卡在配额校验上——所以问题往往出现在数据量上来之后,而不是建表那一刻。











