三、解决数据库乱码原理特辑内容
3.1 前言
在解决数据库乱码问题中,涉及到三个方面的字符集:1、oracel server端的字符集;2、oracle client端的字符集;3、dmp文件的字符集(只有在需要往数据库里面导入dmp文件的时候会涉及到这点)。
3.2 知识储备
查看Oracle客户端字符集:
SELECT * FROM V$NLS_PARAMETERS;--返回当前用户环境中设置的字符集
SELECT USERENV('language') FROM DUAL;--返回当前会话使用的字符集
特别说明:客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符,如果多个设置存在的时候,NLS作用优先级别:Sql function > alter session > 环境变量>注册表>参数文件> 数据库默认参数
查看Oracle服务端字符集:
SELECT * FROM NLS_DATABASE_PARAMETERS;--返回Oracle server端的字符集,来源于props$,是表示数据库的字符集
查看dmp文件的字符集:
用oracle的exp工具导出的dmp文件也包含了字符集信息,dmp文件的第2和第3个字节记录了dmp文件的字符集。如果dmp文件不大,比如只有几M或几十M,可以用UltraEdit打开(16进制方式),看第2第3个字节的内容,如0354,然后用以下SQL查出它对应的字符集:
“select nls_charset_name(to_number('0354','xxxx')) from dual;”
如果dmp文件很大,比如有2G以上(这也是最常见的情况),用文本编辑器打开很慢或者完全打不开,可以用以下命令(在unix主机上):
“cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6”
然后用上述SQL也可以得到它对应的字符集
NLS_LANG参数格式:
Language_Territory.Clientcharacterset
其中,Language显示oracle消息,校验,日期命名,Territory指定默认日期、数字、货币等格式Clientcharacterset指定客户端将使用的字符集。比如NLS_LANG=AMERICAN_AMERICA.US7ASCII。AMERICAN是语言,AMERICA是地区,US7ASCII是客户端字符集。在解决客户端和服务端编码不一致问题导致的乱码时,Language和Territory可以不一致,但是Clientcharacterset必须一致。
其他数据库字符集查询相关语句:
实例字符集环境
SELECT * FROM NLS_INSTANCE_PARAMETERS;--显示由参数文件init.ora定义的参数
主要涉及NLS_LANGUAGE、NLS_TERRITORY的值. NLS_INSTANCE_PARAMETERS其来源于v$parameter,注意:网上很多资料都说"NLS_INSTANCE_PARAMETERS 表示客户端的字符集的设置,可以是参数文件,环境变量或者是注册表",而且网上都人人亦云。记住它是表示实例的字符集环境
数据库可用字符集参数设置
SELECT * FROM V$NLS_VALID_VALUES
会话字符集环境
SELECT * FROM NLS_SESSION_PARAMETERS;
它来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是ALTER SESSION完成,如果会话没有特殊的设置,将与 V$NLS_PARAMETERS一致
设置ORACLE的语言以及编码,添加环境变量:“NLS_LANG = SIMPLIFIED CHINESE_CHINA.AL32UTF8”,
(SIMPLIFIED CHINESE_CHINA.AL32UTF8是中文UTF8编码类型,其它类型可通过语句select userenv(‘language’)from dual进行查询,如果编码不对,会产生乱码