Oracle迁移PostgreSQL时CHR(14844072)报编码字符过大错误咨询
错误产生原因
- 两边数据库
CHR()函数的入参解析逻辑存在本质差异:- Oracle的
CHR()在传入大于255的整数时,会将整数按从高到低的顺序拆分为单字节序列,再按当前数据库字符集解析为对应字符。你传入的14844072转十六进制为0xE280A8,拆成3个UTF-8字节就是0xE2、0x80、0xA8,对应Unicode字符U+2028(行分隔符,也就是你查询得到的不可见空白字符)。 - PostgreSQL默认使用UTF8编码时,
CHR()的入参要求是Unicode标准码点值,合法范围是1~1114111(即0x10FFFF)。你传入的14844072远超过合法码点上限,因此抛出「字符超出编码支持范围」的错误。
- Oracle的
适配方案
根据迁移场景选择其中一种即可:
- 单语句直接适配:直接传入目标字符对应的真实Unicode码点,执行以下SQL即可得到和Oracle完全一致的结果:
其中8232就是字符U+2028的十进制码点值。select CHR(8232); - 批量兼容原有写法:如果业务代码里大量存在Oracle风格的
CHR(大整数)写法,可以自定义一个兼容函数模拟Oracle的CHR逻辑,后续直接调用该函数即可,无需逐句修改入参:
函数创建后,执行CREATE OR REPLACE FUNCTION chr_oracle(p_code integer) RETURNS text AS $$ DECLARE v_bytes bytea := ''; v_remain integer := p_code; BEGIN IF p_code < 256 THEN RETURN CHR(p_code); END IF; WHILE v_remain > 0 LOOP v_bytes := SET_BYTE(('\x00'::bytea || v_bytes), 0, v_remain % 256); v_remain := v_remain / 256; END LOOP; RETURN convert_from(v_bytes, 'UTF8'); END; $$ LANGUAGE plpgsql IMMUTABLE;select chr_oracle(14844072);即可得到和Oracle原语句完全一致的返回结果。
内容的提问来源于stack exchange,提问作者MAK
相关产品推荐
相关产品推荐

