暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

1887.Oracle 生僻字乱码问题

原创 张鹏 2023-10-17
46

1887.Oracle 生僻字乱码问题

就一般情况来说,Oracle存储中英文的字段用varchar2类型就可以了,但有些时候,遇到生僻字就不行了。
需求描述: 在默认字符集环境下,实现Oracle储存生僻字: 㛃、䶮…(使用nvarchar2字段类型实现,以“㛃”为代表进行测试)
1.查看当前使用的字符集 。
select userenv(‘language’) from dual;

一般来说,在安装Oracle数据库的时候,字符集设置选择的是使用默认值,也就是 ZHS16GBK
2.建立测试表。

varchar2 跟 nvarchar2 区别不大,但是在存放中文的时候,nvarchar2会比varchar2多一点。
3.插入测试数据。

显而易见,这两种类型都行不通了。然而,我们可以换一下插入方法
首先,把生僻字转换为Unicode。链接http://www.bejson.com/convert/unicode_chinese/
“㛃” 转为Unicode为 “\u36c3”(注意: \u 是Unicode的转义字符,使用的时候要去掉)
然后,从dual中查询结果:
select utl_raw.cast_to_varchar2(‘36c3’) from dual;

select utl_raw.cast_to_nvarchar2(‘36c3’) from dual;

可见,实质上,在nvarchar2才存储了“㛃”字
最后,再一次进行插入数据:

nvarchar2类型的TNAME成功插入了生僻字“㛃”。
4.最后一点。
虽然说这个问题一般在很小的项目下不会经常遇到,但是还是有它存在的意义的。说不定哪一天你录入数据的时候,姓名会带有生僻字,然后惊奇发现数据变成 ? 了,然后,百度谷歌一找,各有各的说法,各有各的方案,然而…实用的?凉凉。作为过来人我觉得我有必要总结一下这个干货吧,希望能帮到有需要的人,欢迎转载,记得带上原文链接就好。
至于有人说通过更改数据库的字符集也可以实现,可以啊,但是这个代价和工作量过分点了吧?万一出现什么差池,后果太美不敢想象。除非在立项初期,考虑十分周到,囊括所有编码的问题,但是,这个,也有点玄。

oracle–dblink跨库中文乱码解决

场景:数据库B需要数据库A的数据信息
数据库A: US7ASCII
数据库B: ZHS16GBK
dblink A->B : to_b
SELECT * FROM pats_in_hospital@to_b 发现中文字段乱码
原因:
作为dblink的两端,在A通过to_b访问B数据库时,A为B的客户端,由于数据库A的字符集为WE8DEC,为了使A数据库服务器上的其他应用正常使用,所以在A数据库服务器上的已经设置环境变量NLS_LANG=AMERICAN_AMERICA.US7ASCII,而此客户端字符集和B数据库的核心字符集ZHS16GBK不同,因此在返回结果时,要进行字符集转换,但由于US7ASCII和ZHS16GBK不兼容,因此转换失败,出现乱码;

解决方法:
方法一 [试验无效]
在A数据库上修改环境变量NLS_LANG为AMERICAN_AMERICA.ZHS16GBK,使其和数据库核心字符集兼容的字符集;
这样做法,存在一个较难接受的问题,即A数据库服务器上的应用例如sqlplus、exp等,需要每次运行时考虑NLS_LANG的设置。

方法二:使用UTL_RAW包进行处理
【可行,但需要对中文字段V_COLUMN逐个转换较为麻烦,】
1、先转换成十六进制
V_COLUMN_MID := UTL_RAW.CAST_TO_RAW(V_COLUMN);
2、再转换成字符串
V_COLUMN_STR := utl_raw.cast_to_varchar2(V_COLUMN_MID)
3、转码
参数说明:待转字符串,本地字符集
convert(V_COLUMN_STR , ‘ZHS16GBK’);

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论