经常会遇到一些ldquo;为什么我的查询显示乱码?rdquo;或者ldquo;为什么我导入后中文变成乱码?rdquo;的问题,如果想彻底搞懂
经常会遇到一些“为什么我的查询显示乱码?”或者“为什么我导入后中文变成乱码?”的问题,如果想彻底搞懂原因,需要研究下oracle的字符集以及他们之间的转换的关系,还有os字符集、nls_lang跟数据库字符集的关系。简单的总结下要搞懂的几个要点:
1. nls_lang数据库:保证字符相同,存储的2进制可变。
osnls_lang:存储的2进制不变,字符可能显示不同。
2. 如果nls_lang设置成跟数据库字符集一样,则通过oracle net传递数据时存储的2进制不会发生转换。如果不一样,则会发生转换。
3. nls_lang并不是我们以为的用来显示给我们的字符的编码,真正用来显示的编码是os编码,所以如果nls_lang跟os编码不一样时,同一个2进制串可能就会由本来的‘你’显示成‘靠’。
4. 向数据库传递字符时应尽量将nls_lang设置成os字符集,以保证输入的‘我’到nls_lang一层不会发生字符变化,,从而保证到数据库端存储的就是‘我’;
不过使用exp等客户端工具导出时,应尽量将nls_lang设置成数据库字符集,以保证导出时数据原封不动,不会发生数据丢失的可能。导入时也应尽量将nls_lang设成导出文件的字符集,以保证将转换移至传输到数据库的一步。(exp,imp也可能会发生数据丢失问题,具体要看源数据库,exp客户端nls_lang,imp客户端nls_lang,目标数据库的字符集)
5.其实乱码,说到底就是用于显示字符的操作系统没有在字符编码中找到对应的字符导致的,也并不是只要将nls_lang设置成数据库字符集就可以避免乱码的。
贴两张eygle的转换图: