场景解决之Oracle数据库特殊字符或生僻字乱码

问题背景

今天收到一贵客投诉,支付完成订单后无法查询订单。经过排查,问题最终定位于通过用户三要素查询订单时,姓氏正常,但是名显示为"?"(正常情况应该是“䶮”),从而不满足条件无法查询。

排查经过

首先排除服务器的字体的原因,因为在日志上看着是正常的。
再次排除起前后端交互的原因,因为在日志上看着是正常的。
最后排除jdbc的交互原因,因为jdbc的url后面添加了编码类型。而且其他字段都正常,仅仅这一个字不正常。

所以大概率在数据库的字符集上,询问dba,当前公司使用的oracle字符集是GBK,问题差不多摸清楚了。

问题原因

GBK字符集是一种广泛使用的编码标准,用于简体中文字符。然而,它并不包含所有Unicode字符。当遇到不在GBK编码范围内的字符时,这些字符在数据库中可能显示为乱码或问号。

解决方案

1. 转换字段类型

考虑到GBK字符集的限制,一种解决方案是将存储这些特殊字符的字段转换为Unicode支持的字段类型。

  • 添加新列:在现有的表中添加一个新列,选择NVARCHAR2类型,它支持Unicode字符。
  • 复制数据:将现有数据复制到新的NVARCHAR2列,对于不兼容的字符,可能需要一些转换逻辑。
  • 更新应用程序:确保应用程序能够处理新的Unicode字段,并且在应用程序层面上使用正确的字符集。
2. 调整客户端连接字符集

如果问题在于客户端显示,那么可能需要在客户端的连接字符串中明确指定字符集。

在连接数据库时,在连接字符串中指定characterEncoding=GBK,这样可以确保客户端和数据库之间正确地传递字符数据。
3. 数据库字符集迁移
对于长期解决方案,可以考虑迁移整个数据库的字符集到AL32UTF8。

字符集迁移:这是一个比较复杂和耗时的过程,需要进行充分的规划和测试。迁移过程可能涉及到系统的停机时间,因此在进行迁移之前应该进行充分的评估和准备。

4. 使用转义字符(临时解决方案)

将无法存储的字符转换为它们的Unicode转义序列。
这允许将特殊字符作为一种编码形式存储在数据库中,虽然这不是最优雅的解决方案,但它可以作为一个快速修复。当前我就是用的这种。

结语

处理数据库字符集问题时,务必谨慎并充分测试任何变更。在对数据库进行结构性调整之前,确保备份所有数据,并在非生产环境中进行测试。如果你不确定如何操作,或者觉得任务超出了你的技术范围,最好咨询经验丰富的数据库管理员。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
由于历史的原因,早期的oracle没有中文字符集(如oracle6、oracle7、oracle7.1),但有的用户从那时起就使用数据库了, 并用US7ASCII字符集存储了中文,或是有的用户在创建数据库时,不考虑清楚,随意选择一个默认的字符集,如WE8ISO8859P1或US7ASCII,而这两个字符集都没有汉编码,虽然有些时候选用这种字符集好象也能正常使用,但用这种字符集存储汉信息从原则上说就是错误的,它会给数据库的使用与维护带来一系列的麻烦。正常情况下,要将汉存入数据库数据库字符集必须支持中文,而将数据库字符集设置为US7ASCII等单字符集是不合适的。US7ASCII字符集只定义了128个符号,并不支持汉。另外,如果在SQL*PLUS中能够输入中文,操作系统缺省应该是支持中文的,但如果在NLS_LANG中的字符集设置为US7ASCII,显然也是不正确的,它没有反映客户端的实际情况。但在实际应用中汉显示却是正确的,这主要是因为Oracle检查数据库与客户端的字符集设置是同样的,那么数据在客户与数据库之间的存取过程中将不发生任何转换,但是这实际上导致了数据库标识的字符集与实际存入的内容是不相符的。而在SELECT的过程中,Oracle同样检查发现数据库与客户端的字符集设置是相同的,所以它也将存入的内容原封不动地传送到客户端,而客户端操作系统识别出这是汉编码所以能够正确显示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neoest

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值