必须用 modify partition add subpartition 给 range-list 表批量加子分区,仅限已存在主分区,子分区值须符合原 list 定义且在 default 前定义,名称全局唯一,online 不规避主分区锁。

必须用 MODIFY PARTITION ADD SUBPARTITION,不能用 ADD PARTITION
给已有范围-列表(RANGE-LIST)组合分区表批量加子分区,唯一合法语法是 ALTER TABLE ... MODIFY PARTITION ... ADD SUBPARTITION。误写成 ADD PARTITION ... SUBPARTITION 或漏掉 MODIFY PARTITION 会直接报错:ORA-00905: missing keyword 或 ORA-14048: invalid partition operation。
关键约束有三点:
- 只能往**已存在的主分区**(如
P202501)里加子分区,不能凭空新建主分区再加子分区 - 子分区类型由建表时
SUBPARTITION BY LIST (col)固定,后续不能改;比如原定义按status列做列表子分区,新加的子分区就只能带VALUES ('A')、VALUES ('B')这类离散值 - 如果主分区下已有
DEFAULT子分区,新子分区必须在DEFAULT之前定义,否则插入匹配值时可能被DEFAULT拦截,而非落到你预期的子分区
批量加子分区前,先查清主分区和现有子分区状态
盲目执行 ADD SUBPARTITION 容易因重复定义或值冲突失败。务必先确认目标主分区是否存在、当前有哪些子分区、列值域是否覆盖新增值。
查主分区是否存在:
SELECT partition_name FROM user_tab_partitions WHERE table_name = 'YOUR_TABLE' AND partition_name = 'P202501';
查该主分区下已有子分区及对应值:
SELECT subpartition_name, high_value FROM user_tab_subpartitions WHERE table_name = 'YOUR_TABLE' AND partition_name = 'P202501';
常见错误包括:
-
ORA-14400: inserted partition key does not map to any partition:新加的VALUES ('NEW_STATUS')不在该列业务允许值范围内,或已被其他子分区占用 - 执行时提示“partition does not exist”:传入的主分区名拼写错误,或该主分区尚未创建(需先用
ADD PARTITION补上主分区)
LIST 子分区批量添加脚本写法与边界避坑
假设你要为 2025 年 1–12 月每个主分区(P202501–P202512)都加三个状态子分区:ACTIVE、INACTIVE、DRAFT。不能一次性对多个主分区操作,必须逐个 MODIFY。
安全写法示例(以 P202501 为例):
ALTER TABLE orders MODIFY PARTITION P202501
ADD SUBPARTITION P202501_ACTIVE VALUES ('ACTIVE'),
SUBPARTITION P202501_INACTIVE VALUES ('INACTIVE'),
SUBPARTITION P202501_DRAFT VALUES ('DRAFT');
注意点:
- 一条语句可加多个子分区,用逗号分隔,比循环执行 3 次更高效
- 所有
VALUES必须是单引号包裹的字面量,且与列定义类型严格一致(如status VARCHAR2(20),就不能写VALUES (1)) - 若某主分区已有
DEFAULT子分区,这三条必须放在DEFAULT定义语句之前——但 DDL 中不体现顺序,所以实际要先查、再确保没DEFAULT,或删掉再重建(高风险,慎用)
ONLINE 加子分区仅限 Oracle 12c+,且不解决锁竞争
Oracle 12c 及以后支持 ONLINE 子句,例如:
ALTER TABLE orders MODIFY PARTITION P202501
ADD SUBPARTITION P202501_ARCHIVED VALUES ('ARCHIVED') ONLINE;
但它只保证 DDL 执行期间表可读写,**不规避对目标主分区的排他锁**。如果该主分区正被大量 DML 占用,ONLINE 仍会等待或超时。
真正影响批量效率的是子分区数量和底层段扩展开销。加几十个子分区可能触发多次数据字典更新和缓存刷新,建议避开业务高峰执行,并监控 DBA_SEGMENTS 确认新子分区段是否成功生成。
最易被忽略的一点:复合分区的子分区名全局唯一。如果你在不同主分区下都用了 SUB_A 这种简短名,Oracle 会报 ORA-14035: duplicate subpartition name —— 名字必须在整个表内唯一,别图省事。











