必须用 ALTER TABLE ... MODIFY PARTITION ... ADD SUBPARTITION,不能用 ADD PARTITION;子分区只能加在已存在的主分区内,且受原分区类型和子分区策略严格约束。
直接说结论:必须用 alter table ... modify partition ... add subpartition,不能用 add partition;子分区只能加在已存在的(主)分区内,且受原分区类型和子分区策略严格约束。
MODIFY PARTITION ADD SUBPARTITION 语法要点
这是唯一合法路径。常见错误是误写成 ADD PARTITION ... SUBPARTITION 或漏掉 MODIFY PARTITION 关键字,会报 ORA-00905: missing keyword 或 ORA-14048: invalid partition operation。
-
MODIFY PARTITION后必须指定**已存在**的主分区名,比如P202604,不能是新分区名 -
ADD SUBPARTITION后跟子分区名(如SUB_202604_A),再跟VALUES条件(列表分区)或VALUES LESS THAN(范围子分区) - 若原表是复合分区(如 RANGE-LIST),子分区类型由建表时定义固定,不可临时更改;例如建表时用
SUBPARTITION BY LIST (status),就只能加VALUES ('ACTIVE')类型子分区 - Oracle 12c 及以后支持
ONLINE子句(如MODIFY PARTITION ... ADD SUBPARTITION ... ONLINE),但仅限部分场景,且需注意锁行为
列表子分区(LIST-SUBPARTITION)怎么加
适用于按离散值(如地区代码、状态码)做二级划分。典型错误是 VALUES 值超出原列定义域,或重复插入已存在的值,导致 ORA-14400: inserted partition key does not map to any partition。
- 先查清目标主分区当前有哪些子分区:
SELECT SUBPARTITION_NAME, HIGH_VALUE FROM USER_TAB_SUBPARTITIONS WHERE TABLE_NAME = 'YOUR_TABLE' AND PARTITION_NAME = 'P202604' - 确保新加的
VALUES ('NEW_STATUS')在该列的业务取值范围内,且未被其他子分区占用 - 示例语句:
ALTER TABLE orders MODIFY PARTITION P202604 ADD SUBPARTITION P202604_NEW VALUES ('DRAFT') - 如果原主分区下已有 DEFAULT 子分区,新加子分区必须在 DEFAULT 之前定义,否则后续插入可能意外落入 DEFAULT 而非预期分区
范围子分区(RANGE-SUBPARTITION)边界怎么设
多用于时间+维度组合场景(如按月再按ID段)。最容易踩的坑是边界重叠或留空,导致数据无法写入或被裁剪到错误子分区。
- 子分区
HIGH_VALUE必须严格大于前一个子分区的HIGH_VALUE,且小于主分区的HIGH_VALUE - 例如主分区
P202604定义为VALUES LESS THAN (DATE'2026-05-01'),则子分区可设VALUES LESS THAN (DATE'2026-04-16')和VALUES LESS THAN (DATE'2026-05-01'),但不能设VALUES LESS THAN (DATE'2026-05-15')(超主分区上限) - 建议用
TO_DATE显式格式化,避免 NLS 设置影响解析,如TO_DATE('2026-04-16', 'YYYY-MM-DD') - 添加后立即验证:
INSERT INTO your_table VALUES (...)测试关键边界数据是否落入预期子分区
容易被忽略的三个硬限制
这些不是报错才出现,而是静默失败或后期引发严重问题:
- 全局索引不会自动维护——添加子分区后,若表上有全局索引,
SELECT可能返回错误结果,必须手动ALTER INDEX ... REBUILD或改用本地索引 - 间隔分区(INTERVAL)表不支持直接
MODIFY PARTITION ... ADD SUBPARTITION;必须先转为普通范围分区(SET INTERVAL ()),再操作,否则报ORA-14758: Last partition in the range section cannot be dropped - 子分区名长度不能超过 30 字节,且不能与现有子分区名重复;Oracle 会自动截断或报
ORA-00972: identifier is too long,但不会提示截断逻辑


















