结论是用alter user ... quota设置配额,禁用unlimited tablespace;查dba_ts_quotas为空即表示无配额(等价quota 0),非默认允许,此时有create table权限也会因缺配额报ora-01950。

直接给结论:用 ALTER USER ... QUOTA 设置,别碰 UNLIMITED TABLESPACE,否则配额形同虚设。
查不到配额记录?那用户其实没配额
执行 SELECT * FROM DBA_TS_QUOTAS WHERE username = 'SCOTT'; 返回空,不是“默认允许”,而是“默认禁止”。Oracle 不会自动给任何用户配额,没显式设置 = 等价于 QUOTA 0 ON tablespace_name。这时候哪怕用户有 CREATE TABLE 权限,建表也会报 ORA-01950: no privileges on tablespace 'USERS' —— 错误名误导人,实际是缺配额,不是缺权限。
要确认真实状态,必须查 DBA_TS_QUOTAS;只看 DBA_USERS.DEFAULT_TABLESPACE 没用,它不反映配额。
设配额必须用 ALTER USER,不是 GRANT
GRANT QUOTA ON TABLESPACE 是无效语法,Oracle 不支持。唯一合法方式是:
-
ALTER USER scott QUOTA 10M ON users;—— 允许最多 10MB -
ALTER USER scott QUOTA 0 ON users;—— 禁止在该表空间创建任何段(包括空表) -
ALTER USER scott QUOTA UNLIMITED ON users;—— 表空间级放开,仅对users生效
注意:QUOTA 0 不删已有对象,但后续 INSERT 或 DDL 触发新 extent 分配时,会立即报 ORA-01536: space quota exceeded。
UNLIMITED TABLESPACE 权限会绕过所有配额
一旦执行了 GRANT UNLIMITED TABLESPACE TO scott;,所有 QUOTA 设置自动失效,DBA_TS_QUOTAS 里也查不到记录。这不是“更宽松的配额”,而是彻底跳过配额校验机制。
生产环境应避免授予此权限。如果真要放开,优先选 ALTER USER ... QUOTA UNLIMITED ON xxx,至少控制范围明确。
撤销时也得对应:REVOKE UNLIMITED TABLESPACE FROM scott;,而不是试图用 QUOTA 0 覆盖。
配额只管永久段,临时和回滚段完全不生效
QUOTA 只约束用户在永久表空间中创建的段:表、索引、LOB、物化视图等。以下操作不受影响:
- 排序、哈希连接产生的临时段 → 走
TEMPORARY TABLESPACE,由用户TEMPORARY TABLESPACE属性决定 - 事务回滚段 → 走
UNDO_TABLESPACE,由系统自动管理 - 全局临时表数据 → 同样走临时表空间
想限制临时空间用量,得改用户的 TEMPORARY TABLESPACE 指向一个资源受限的临时表空间,并配合 profile 中的 RESOURCE_LIMIT 和 SESSIONS_PER_USER 等参数。
最容易被忽略的是:配额检查发生在物理分配时刻(比如 INSERT 导致新 extent 分配),不是按周期刷新;且分区表每个分区都独立计入配额,但系统对象(如审计表、物化视图日志)通常属 SYS,不占普通用户额度。











