Oracle列表分区VALUES子句必须用双层括号包裹多个值,如VALUES(('US'),('CN'));多列分区需写成VALUES(('US','A'),('CN','X'));DEFAULT分区可与多值分区共存但须独立定义,且不支持与AUTOMATIC共存。
oracle 列表分区的 values 子句天然支持多个值,无需额外配置,但写法必须严格符合语法——括号不能省、逗号分隔、每个值必须显式包裹在括号内。
VALUES(('US'),('CN'),('JP')) 是正确写法,VALUES('US','CN','JP') 会报错
Oracle 的列表分区 VALUES 不接受扁平化字符串列表。常见错误是直接写 VALUES('US','CN','JP'),这会触发 ORA-14020:this physical attribute may not be specified for this column。真正有效的写法是把每个值单独用小括号包一层,再整体用大括号括起来:
PARTITION p_northamerica VALUES (('US'), ('CA'), ('MX'))
注意:(('US')) 和 (('US'),('CA')) 都合法;但 ('US','CA') 或 VALUES 'US' 均非法。
- 多值写法只适用于单列列表分区(如
PARTITION BY LIST (country_code)) - 若使用多列列表分区(如
PARTITION BY LIST (country_code, record_type)),VALUES必须写成VALUES (('US','A'), ('US','B'), ('CN','X'))—— 每个组合是一对括号,外层再套一层 - 空括号
VALUES ()不被允许,至少填一个值
多值分区与 DEFAULT 分区能否共存?可以,但 DEFAULT 必须是独立分区
你可以在同一张表里既有带多个值的明确分区,也有一个 VALUES (DEFAULT) 分区兜底。这是完全合法的,且常用于避免 ORA-14400 错误:
PARTITION p_usa VALUES (('US'), ('CA')),<br>PARTITION p_eu VALUES (('DE'), ('FR'), ('GB')),<br>PARTITION p_other VALUES (DEFAULT)
关键约束在于:DEFAULT 分区只能有一个,且不能和其他值混写在同一 VALUES 子句里(比如 VALUES (('US'), (DEFAULT)) 是语法错误)。
-
DEFAULT分区不参与值匹配优先级判断,它纯属“最后 fallback” - 一旦定义了
DEFAULT,后续就无法再通过ALTER TABLE ... ADD PARTITION添加新的非 DEFAULT 分区(除非先删掉 DEFAULT) - 如果同时启用了
AUTOMATIC,则DEFAULT和AUTOMATIC互斥,二者不可共存
VALUES 中的值类型必须与分区列类型严格一致
看似 trivial,但实际踩坑最多:字符型列不能传数字字面量,日期列不能传字符串。例如:
- 分区列为
VARCHAR2(2),必须写VALUES (('AB')),不能写VALUES ((AB))(缺引号)或VALUES ((12))(类型不匹配) - 分区列为
NUMBER,可写VALUES ((1), (2), (99)),但不能加单引号变成字符串 - 分区列为
CHAR(2),插入值会自动右补空格,所以VALUES (('US'))和VALUES (('US '))在语义上等价,但建议统一按定义长度书写
隐式转换不会发生——Oracle 在 DDL 解析阶段就校验类型,不依赖运行时。
自动列表分区(AUTOMATIC)下,VALUES 写法被完全绕过
启用 AUTOMATIC 后,你定义的初始分区仍需用 VALUES,但后续新增分区由 Oracle 自动生成,不再走你写的 VALUES 逻辑。这意味着:
- 你建表时写的
PARTITION p_init VALUES (('US'))只影响初始结构,不影响后续自动行为 - 第一次插入
'DE'时,Oracle 创建的分区名类似SYS_P12345,其内部VALUES就是(('DE')),但你无法控制或查看该定义 -
DBMS_METADATA.GET_DDL返回的 DDL 不包含自动生成的分区,所以备份/迁移时容易遗漏数据
真正需要长期维护的,只有你手写的那部分 VALUES;自动创建的部分,得靠 SELECT partition_name FROM user_tab_partitions 定期快照。


















