LIST分区支持CHAR列,但要求VALUES值与存储值字节级完全一致(含Oracle自动填充的尾部空格),否则插入失败或误入DEFAULT分区;推荐改用VARCHAR2避免空格干扰。
list 分区不支持 char 类型列直接分区,但可以正常使用 —— 关键在于值匹配必须完全一致(含空格),否则插入会失败或被误分到 default 分区(如果定义了)。
LIST 分区对 CHAR 列的值匹配是严格字节级的
CHAR 是定长类型,Oracle 会用空格填充到定义长度。比如 area CHAR(10) 存入 'beijing',实际存储为 'beijing '(后面3个空格)。
如果你在 VALUES 子句里写的是 VALUES('beijing'),Oracle 内部会把它也按 CHAR(10) 对齐,变成 'beijing ',匹配成功。
但如果你用的是绑定变量、应用传入的 VARCHAR2 值,或显式 rtrim,就很可能不匹配。
- 常见错误现象:
ORA-14400: inserted partition key does not map to any partition - 根本原因:插入值(如
'shanghai')与分区定义中VALUES('shanghai')表面相同,但因长度不一致导致二进制不等 - 验证方式:用
DUMP()查看两边实际字节序列,例如SELECT DUMP('shanghai') FROM DUAL;和SELECT DUMP(area) FROM your_list_table WHERE ROWNUM = 1;
创建 LIST 分区表时,CHAR 列要统一按目标长度声明并显式对齐
明确指定
CHAR长度,且所有分区VALUES字符串长度必须与其一致不要用
VARCHAR2列去匹配CHAR分区键(隐式转换不可靠)-
示例(安全写法):
CREATE TABLE cust_region ( id NUMBER, region_code CHAR(6) ) PARTITION BY LIST (region_code) ( PARTITION p_north VALUES ('BJ '), PARTITION p_south VALUES ('GD '), PARTITION p_east VALUES ('SH ') );注意:每个VALUES字符串都补足了4个空格,与CHAR(6)定义对齐 -
更稳妥的做法:把分区键列定义为
VARCHAR2,避免空格干扰region_code VARCHAR2(6)
这样VALUES('BJ')就能自然匹配,无需手动补空格
插入数据前必须确保值与分区定义的字节完全一致
- 应用层传入的值如果是
VARCHAR2,且列是CHAR,Oracle 会自动右填空格 —— 但前提是 没有触发隐式类型转换或截断 - 容易踩的坑:
- 使用 PL/SQL 变量赋值时未用
RPAD对齐 - JDBC 中设置
setString()传入短字符串,驱动未做空格填充(行为依赖 driver 版本) - 触发器或函数返回值类型与分区键类型不一致
- 使用 PL/SQL 变量赋值时未用
- 建议插入前校验:
INSERT INTO cust_region VALUES (1, RPAD('BJ', 6));
真正麻烦的不是语法写不对,而是 CHAR 的隐式填充和 DUMP 看不见的空格,在批量导入或跨系统对接时悄无声息地破坏分区路由。











