Perl DBI::Oracle连接Oracle XE查询UTF8字符编码异常原因问询
问题成因解释
核心原因是Perl的字符串存在两种存储模式,以及DBI::Oracle的默认字符转换逻辑共同导致的:
- 当你配置
NLS_LANG=AMERICAN_AMERICA.UTF8连接Oracle时,Oracle客户端会自动将数据库返回的UTF-8编码字节串解码为Perl内部的Unicode字符串。你看到的\x{e4}就是字符ä对应的Unicode码点值,而你预期的c3a4是该字符做UTF-8编码后的字节序列,二者本质语义一致,只是存储形式不同。 unpack('H*')的输出结果和输入字符串的存储模式强相关:输入是字节串时输出字节的十六进制值,输入是Unicode字符串时输出每个字符的码点十六进制值。你脚本里写死的ä字面量是UTF-8编码的字节串,所以第1行输出c3a4;从数据库返回的是解码后的Unicode字符串,所以第6、7行输出e4。- 第2、3行的
rawtohex查询返回的是数据库中存储的原始字节的十六进制,结果为C3A4也验证了数据库侧确实是按UTF-8编码存储ä字符的,不存在数据库侧的编码错误。 - 第5行能正常打印出
ä也验证了返回字符的语义是正确的,只是存储形式不符合你的预期。
调整方案
如果需要拿到UTF-8编码的字节串,可以对查询返回的结果做显式编码:
- 引入
Encode模块:use Encode qw(encode_utf8); - 对查询返回的字符串调用
encode_utf8()方法后再处理,即可得到编码为c3a4的字节串。
内容的提问来源于stack exchange,提问作者matthias
相关产品推荐
相关产品推荐

