Oracle中CHAR(1)经MAX聚合UNION NULL后长度异常扩展至32767字节
CHAR(1)经聚合+UNION后在PL/SQL中被填充至32767字节的问题
有人遇到过这种情况吗?这到底是Bug还是特性?CHAR(1)类型的值在特定场景下会被空格填充到PL/SQL字符串最大长度32767字节,导致下游仅预期1字符的逻辑出现异常。
简单测试案例
BEGIN FOR rec_data IN (SELECT MAX('Y') bind_all_ips FROM dual UNION ALL SELECT NULL bind_all_ips FROM dual) LOOP dbms_output.put_line('bind_all_ips length = '||LENGTH(rec_data.bind_all_ips)); END LOOP; END;
输出:
bind_all_ips length = 32767
数据表测试案例
create table tab1 (bind_all_ips char(1)); insert into tab1 values ('Y'); commit; BEGIN FOR rec_data IN (SELECT MAX(bind_all_ips) bind_all_ips FROM tab1 UNION ALL SELECT NULL bind_all_ips FROM dual) LOOP dbms_output.put_line('bind_all_ips length = '||LENGTH(rec_data.bind_all_ips)); END LOOP; END;
输出:
bind_all_ips length = 32767
问题触发条件
需同时满足以下所有条件:
- 使用CHAR数据类型
- 对该字段执行MAX()或MIN()聚合查询
- 将该查询与指定同一列为NULL的查询进行UNION操作
- 通过PL/SQL隐式游标获取结果
临时解决方法
可通过显式转换为VARCHAR2规避此问题,例如将聚合查询改为MAX(TO_VARCHAR2(bind_all_ips))。
更新:
该行为在包括8.1.7(可能更早版本)在内的多个Oracle版本中存在:
- 9.2.0.6至12.1.0.2版本中,填充后的长度为4000字节
- 9.2.0.3至9.2.0.5版本无此问题,返回正常的1字节长度
- 12.2.0.1至19.20(可能更晚版本)中,填充后的长度为32767字节
2023年10月27日更新:
Oracle官方已确认这是一个Bug,并已在21c至23c之间的某个版本中修复。
内容的提问来源于stack exchange,提问作者Paul W
相关产品推荐
相关产品推荐

