oracle中的数据库乱码的原因与解决

 “在 SQL *Plus中用insert插进的都是中文的,为什么一存入服务器后,再select出的就是???” 
  
  “有的时候,服务器数据先导出,重装服务器,再导入数据,结果,发生数据查询成???” 
  
  …… 
  

  这些问题,一般是因为字符集设置不对造成的。 


oracle 如果server与client端的编码不一致, asp.net读取db记录显示时,就可能出现乱码
查看oracle服务端编码:select * from sys.nls_database_parameters;
查看client编码:select * from sys.nls_session_parameters;    www.2cto.com  
如果二端编码不一致,可以修改客户端的编码:
 
regedit打开注册表:
HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/KEY_OraDb10g_home1
修改NLS_LANG的值,一般为 SIMPLIFIED CHINESE_CHINA.ZHS16GBK (简体中文编码,这也是oracle安装时默认的编码),如果服务端是utf8,该值需要修改成SIMPLIFIED CHINESE_CHINA.AL32UTF8
tips:如果不记得字符串,也可以通过在服务端运行 select userenv('language') from dual; 查看
 

  
  很久以来,字符集一直是困扰着众多Oracle爱好者的问题,笔者从事Oracle 数据库 管理和应用已经几年了,经常接到客户的类似上面提到的有关 数据库 字符集的“告急”和“求救”,在此我们就这个问题做一些分析和探讨。 
  
  首先,我们要明确什么是字符集?字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包括关系,如us7ascii就是zhs16gbk的子集,从us7ascii到zhs16gbk不会有数据解释上的问题,不会有数据丢失,Oracle对这种问题也要求从子集到超集的导出受支持,反之不行。在所有的字符集中utf8应该是最大,因为它基于unicode,双字节保存字符(也因此在存储空间上占用更多)。 
  
  其次,一旦数据库创建后,数据库的字符集是不能改变的。因此,在设计和安装之初考虑使用哪一种字符集是十分重要的。数据库字符集应该是操作系统本地字符集的一个超集。存取数据库的客户使用的字符集将决定选择哪一个超集,即数据库字符集应该是所有客户字符集的超集。 
  
  在实际应用中,和字符集问题关系最大的恐怕就是exp/imp了。在做exp/imp时,如果Client 和Server的nls_lang设置是一样的,一般就没有问题的。但是,要在两个不同字符集的系统之间导数据就经常会有这样或那样的问题,如,导出时数据库的显示正常,是中文,当导入到其他系统时,就成了乱码,这也是一类常见问题。 
  
  现在,介绍一些与字符集有关的NLS_LANG参数, 
  
   NLS_LANG格式:  
  NLS_LANG = language_territory.charset 
  
  有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。其中:language 指定服务器消息的语言。 
  
  territory 指定服务器的日期和数字格式。 
  
  charset 指定字符集 
  
   例如:  
  AMERICAN_AMERICA.US7SCII 
  
  AMERICAN _ AMERICA. ZHS16GBK 
  
  
   还有一些子集可以更明确定义NLS_LANG参数:  
  DICT.BASE 数据字典基本 表版本 
  
  DBTIMEZONE 数据库时区 
  
  NLS_LANGUAGE 语言 
  
  NLS_TERRITORY 地域 
  
  NLS_CURRENCY 本地货币字符 
  
  NLS_ISO_CURRENCY ISO货币字符 
  
  NLS_NUMERIC_CHARACTERS 小数字符和组 分隔开 
  
  NLS_CHARACTERSET 字符集 
  
  NLS_CALENDAR 日历系统 
  
  NLS_DATE_FORMAT 缺省的日期格式 
  
  NLS_DATE_LANGUAGE 缺省的日期语言 
  
  NLS_SORT 字符排序序列 
  
  NLS_TIME_FORMAT 时间格式 
  
  NLS_TIMESTAMP_FORMAT 时间戳格式 
  
  …… 
   通过props$动态性能视图,我们可以查看数据库的字符集信息:  
  $> sqlplus internal 
  
  SQL> desc props$ 
  
  Name Type Nullable Default Comments 
  
  NAME VARCHAR2(30) 
  
  VALUE$ VARCHAR2(4000) Y 
  
  COMMENT$ VARCHAR2(4000) Y 
  
  SQL> set arraysize 1 
  
  SQL> col value$ format a40 
  
  SQL> select name,value$ from props$ where name=‘NLS_CHARACTERSET’; 
  
  NAME VALUE$ 
  
  NLS_CHARACTERSET ZHS16GBK 
  
  SQL> select * from sys.props$; 
  
  NAME VALUE$ 
  
  DICT.BASE 2 
  
  DBTIMEZONE 0:00 
  
  NLS_LANGUAGE AMERICAN 
  
  NLS_TERRITORY AMERICA 
  
  NLS_CURRENCY $ 
  
  NLS_ISO_CURRENCY AMERICA 
  
  NLS_NUMERIC_CHARACTERS ., 
  
  NLS_CHARACTERSET ZHS16GBK 
  
  NLS_CALENDAR GREGORIAN 
  
  NLS_DATE_FORMAT DD-MON-RR 
  
  NLS_DATE_LANGUAGE AMERICAN 
  
  NLS_SORT BINARY 
  
  NLS_TIME_FORMAT HH.MI. SSXFF AM 
  
  NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM 
  
  NLS_TIME_TZ_FORMAT HH.MI. 
  
  SSXFF AM TZH:TZM 
  
  NLS_TIMESTAMP_TZ_FORMAT DD-MON- RR HH.MI. SSXFF AM TZH:TZM 
  
  NLS_DUAL_CURRENCY $ 
  
  NLS_COMP BINARY 
  
  NLS_NCHAR_CHARACTERSET ZHS16GBK 
  
  NLS_RDBMS_VERSION 8.1.6.0.0 
  
  NAME VALUE$ 
  
  GLOBAL_DB_NAME SCPDB1 
  
  EXPORT_VIEWS_VERSION 8 
  
  22 rows selected 
  
  SQL> 
  
   从结果可以看出:  
  NLS_LANG = AMERICAN _ AMERICA. ZHS16GBK 
  
  虽然,数据库的字符集是在create database的时候指定的,以后不允许改变,但在一个已经建立好的数据库上,我们可以通过修改SYS.PROPS$来修改主要是对应客户端的显示,与存储无关。 
  
  如: 
  
  SQL> conn / as sysdba 
  
  Connected. 
  
  SQL> SQL> select * from sys.props$ 
  
  2 WHERE NAME=‘NLS_LANGUAGE’; 
  
  NAME VALUE$ 
  
  NLS_LANGUAGE AMERICAN 
  
  SQL> 
  
  SQL> UPDATE sys.PROPS$ SET VALUE$=‘SIMPLIFIED CHINESE’ 
  
  2 WHERE NAME=‘NLS_LANGUAGE’; 
  
  1 row updated 
  
  SQL> 
  
  SQL> select * from sys.props$ 
  
  2 WHERE NAME=‘NLS_LANGUAGE’; 
  
  NAME VALUE$ 
  
  NLS_LANGUAGE SIMPLIFIED CHINESE 
  
  SQL> 
  
   通常出现问题的原因,可分为三种:  
  1. 服务器指定字符集与客户字符集不同,而与加载数据字符集一致。 
  
  解决方法:对于这种情况,只需要设置客户端字符集与服务器端字符集一致就可以了,具体操作如下: 
  
  * 查看当前字符集: 
  
  SQL> select * from sys.props$ 
  
  2 WHERE NAME=‘NLS_CHARACTERSET’; 
  
  NAME VALUE$ 
  
  
  NLS_CHARACTERSET ZHS16GBK 
  
  SQL> 
  
  可以看出,现在服务器端Oracle数据库的字符集为‘ZHS16GBK’ 
  
  * 根据服务器的字符集在客户端作相应的配置或者安装Oracle的客户端软件时指定: 
  
  如果还没安装客户端,那么在安装客户端时,指定与服务器相吻合的字符集即可;如果已经安装好了客户端,并且客户端为 sql*net 2.0 以下版本,进入Windows的系统目录,编辑oracle.ini文件,用US7ASCII替换原字符集,重新启动计算机,设置生效;否则,如果,客户端为 sql*net 2.0 以上版本,在Win98 下 运 行REGEDIT,第一步选HKEY_LOCAL_MACHINE,第二步选择SOFTWARE, 第三步选择 Oracle, 第四步选择 NLS_LANG, 键 入 与服 务 器 端 相 同 的 字 符 集 
  
  (本例为:HKEY_LOCAL_MACHINE\ 
  
  SOFTWARE\ORACLE\NLS_LANG :AMERICAN _ AMERICA. ZHS16GBK)。 
  
    如果是UNIX客户端,则:  
  SQL> conn / as sysdba 
  
  Connected. 
  
  SQL> SQL> UPDATE sys.PROPS$ SET VALUE$=‘SIMPLIFIED CHINESE’ 
  
  2 WHERE NAME=‘NLS_LANGUAGE’; 
  
  1 row updated 
  
  SQL> COMMIT; 
  
  Commit complete 
  
  SQL> 
  2. 服务器指定字符集与客户字符集相同,与加载数据字符集不一致。 
  
  解决方法:强制加载数据字符集与服务器端字符集一致。要做到这一点,可以通过重新创建数据库,并选择与原卸出数据一致的字符集,然后IMP数据,这种情况仅仅适用于空库和具有同一种字符集的数据。 
  
  解决这类问题,也可以先将数据加载到具有相同字符集的服务器上,然后用转换工具卸出为foxbase 格式或access格式数据库,再用转换工具转入到不同字符集的Oracle数据库中,这样就避免了Oracle字符集的困扰。目前数据库格式转换的工具很多,像power builder5.0以上版本提供的pipeline及Microsoft Access数据库提供的数据导入/导出功能等。 
  
  3. 服务器指定字符集与客户字符集不同,与输入数据字符集不一致。 
  
  对于这种情况,目前为止都还没有太好的解决方法。 
  
  通过上面的了解,我们知道,导致在后期使用数据库时出现种种关于字符集的问题,多半是由于在数据库设计、安装之初没有很好地考虑到以后的需要,所以,我们完全可以通过在服务器上和客户端使用相同的字符集来避免由此类问题引出的麻烦
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值