• 0
  • 0
分享
  • 解锁Oracle数据库测试:三招攻克汉字乱码——软件测试圈
  • quinn 2024-07-04 11:43:14 字数 5868 阅读 2019 收藏 0

  一、背景

  在我们日常的测试工作中,无论在数据迁移还是系统测试过程中,测试数据准确性和可用性是测试工作的重中之重,测试人员经常需要查询数据库中的数据或手工造测试数据,而登到oracle数据库后有时会发现显示中文乱码的情况,如下图所示:

1-1.png

  或者是:

1-2.png

  好好的怎么就乱码了呢?明明“之前”访问其他数据库是没问题。在学习和查询相关资料后我解决了这个问题,但由此引发了我对出现汉字乱码问题的学习兴趣,都是什么原因导致的汉字显示乱码呢?

  首先,字符集设置不当是影响Oracle数据库汉字显示的关键问题。下文则详细介绍了oracle关于字符集的分类、构成及设定方法,分析了ORACLE数据库汉字显示乱码的常见现象及原因,并针对各种现象及原因提出了行之有效的解决办法。

  二、关于字符集

  字符集是ORACLE为适应不同语言文字显示而设定的。用于汉字显示的字符集主要有ZHS16CGB231280、ZHS16GBK、US7ASCII和UTF-8等。字符集同时存在于服务器端和客户端。服务器端字符集是在安装ORACLE时指定的,字符集登记信息存储在ORACLE数据库字典的V$NLS_PARAMETERS表中;而客户端字符集是在系统注册表(WINDOWS系统)或在用户的环境变量(UNIX系统)中设定的。

  三、字符集的构成与设定

  字符集的构成与设定方式分为客户端与服务器端两种:

  (1)客户端字符集的构成与设定

  客户端的字符集是由当前用户的环境变量NLS_LANG设定的。环境变量NLS_LANG的构成:NLS_LANG=language_territory.charset

  其中:

        language 指定服务器消息的语言
        territory   指定服务器的日期和数字格式
        charset    指定字符集

  三个成分可以任意组合,例如:

        AMERICAN_AMERICA.US7SCII
        SIMPLIFIED CHINESE_CHINA.ZHS16GBK
        AMERICAN_AMERICA.ZHS16GBK

  WINDOWS系统是在注册表项:HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/HOME0/NLS_LANG中设定;

  (2)服务端字符集的构成与设定

  服务端字符集的构成体现在数据字典表V$NLS_PARAMETERS的NLS_LANGUAGE、NLS_TERRITORY、NLS_CHARACTERSET三项取值上,其中NLS_CHARACTERSET的取值就是具体的数据库字符集。如利用查询语句SQL>SELECT * FROM V$NLS_PARAMETERS;可得到如下结果:

  PARAMETER                   VALUE
  NLS_LANGUAGE           SIMPLIFIED CHINESE
  NLS_TERRITORY               CHINA
  NLS_CHARACTERSET           ZHS16GBK

  即当前数据库使用的字符集是ZHS16GBK。

  数据库服务端的字符集是在创建数据时设定的。但可通过如下方法对已设定的字符集进行修改:

  方法一:重建数据库。建立数据库时将数据库的字符集设定为所需字符集。

  方法二:修改SYS.PROPS$表。即用SYS用户登陆ORACLE后,利用下面语句修改相应的字符集并提交:SQL>UPDATE PROPS$ SET VALUE$=‘ZHS16GBK’WHERE NAME=‘NLS_CHARACTERSET’;SQL>COMMIT;

  通过此种方法来更改数据库字符集,只对更改后的数据有效,即数据库中原来的数据仍以原字符集被存储。

  方法三:在linux系统下,则需要手动替换整个字符集,具体操作如下:

  1.查看当前数据库字符集

  select * from nls_database_parameters
  where parameter='NLS_CHARACTERSET';
  -----------------------------------
  PARAMETER         VALUE
  NLS_CHARACTERSET WE8ISO8859P1

  2.将字符集修改为中文字符集ZHS16GBK(具体linux版本不同可能存在差异)

  SQL> shutdown immediate
  Database closed.
  Database dismounted.
  ORACLE instance shut down.
  SQL> STARTUP MOUNT;
  ORACLE instance started.
  Total System Global Area  734003200 bytes
  Fixed Size                  1221564 bytes
  Variable Size             264244292 bytes
  Database Buffers          465567744 bytes
  Redo Buffers                2969600 bytes
  Database mounted.
  SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
  System altered.
  SQL> ALTER DATABASE OPEN;
  Database altered.
  SQL> ALTER DATABASE CHARACTER SET ZHS16GBK;
  ALTER DATABASE CHARACTER SET ZHS16GBK
  *
  ERROR at line 1:
  ORA-12712: new character set must be a superset of old character set
  SQL> ALTER DATABASE character set INTERNAL_USE ZHS16GBK;
  Database altered.
  SQL> SHUTDOWN IMMEDIATE;
  Database closed.
  Database dismounted.
  ORACLE instance shut down.
  SQL> startup
  ORACLE instance started.
  Total System Global Area  734003200 bytes
  Fixed Size                  1221564 bytes
  Variable Size             264244292 bytes
  Database Buffers          465567744 bytes
  Redo Buffers                2969600 bytes
  Database mounted.
  Database opened.

  此种方法依旧只对更改后的数据有效,即数据库中原来的数据仍以原字符集被存储。

  另外,有的还利用CREATE DATABASE CHARACTER SET ZHS16GBK命令暂时的修改字符集,当重启数据库后,数据库字符集将恢复原来的字符集。

  四、 查看数据库字符集

  这涉及三方面的字符集:

  一是:oracle server端的字符集;

  二是:oracle client端的字符集;

  三是:dmp文件的字符集;

  在做数据导入的时候,需要这三个字符集都一致才能正确导入。

  2.1查询oracle server端的字符集

  有很多种方法可以查出oracle server端的字符集

  ①比较直观的查询方法

  SQL> select userenv('language') from dual;

  查询结果如下: SIMPLIFIED CHINESE_CHINA.ZHS32GB18030

  ②查看有关字符集的所有参数

  SELECT  * FROM  v$nls_parameters;

  结果中的NLS_CHARACTERSET ZHS32GB18030

  2.2查看dmp文件的字符集

  用oracle的exp工具导出的dmp文件也包含了字符集信息,dmp文件的第2和第3个字节记录了dmp文件的字符集。如果dmp文件不大,比 如只有几M或几十M,可以用UltraEdit打开(16进制方式),看第2第3个字节的内容,如0354,然后用以下SQL查出它对应的字符集:

  SQL> select nls_charset_name(to_number('0354','xxxx')) from dual;ZHS16GBK

  2.3查询oracle client端的字符集

  在windows平台下,就是注册表里面相应OracleHome的NLS_LANG。具体路径:

  Win+R中输入regedit 路径\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\ nls_lang 显示本地的字符集,这样就只影响这个窗口里面的环境变量。

  在unix平台下,就是环境变量NLS_LANG。

  $echo $NLS_LANG

  AMERICAN_AMERICA.ZHS16GBK

  以我行常用的PLSQL Developer为例,在不同oracle版本下的客户端环境变量配置地址不同:

  1.oracle10g注册表说在位置如下:

  ①在windows+R键中输入regedit

  ②\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\ORACLE\KEY_OraDb10g_home1

  ③修改NLS_LANG=“SIMPLIFIED Chinese_CHINA.ZHS16GBK”或

  NLS_LANG=“SIMPLIFIED CHINESE_CHINA.AL32UTF8”等(如图一)

  2.oracle12g注册表位置:HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/KEY_OraDB12Home1/NLS_LANG

  3.oracle11g注册表位置:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\

  4.也有注册表位置:

  在HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/Home0/NLS_LANG的其他oracle版本。

1-3.png

  如果检查的结果发现server端与client端字符集不一致,建议统一修改为同server端相同的字符集。

  五、常见的汉字乱码问题及解决方案(解决方案操作详见三)

  要在客户端正确显示ORACLE数据库中的汉字信息,首先必须使客户端的字符集与服务器端的字符集一致;其次是加载到ORACLE数据库的数据字符集必须与服务器字符集一致。据此,汉字显示乱码的问题大致可以分为以下几种情况:

  (1)客户端字符集与服务器端字符集不同,服务器端字符集与加载数据字符集一致。这种情况是最常见的,只要把客户端的字符集设置正确即可。具体解决方案:

  第一步:查询V$NLS_PARAMETERS得到服务端的字符集:SQL>SELECT * FROM V$NLS_PARAMETERS;

  PARAMETER                       VALUE
  NLS_LANGUAGE            SIMPLIFIED CHINESE
  NLS_TERRITORY                   CHINA             
  NLS_CHARACTERSET              ZHS16GBK

  第二步:根据服务端的字符集设定客户端的字符集,设定方法参见客户端的字符集的设定方式。以UNIX系统为例,可在当前用户的profile文件中增加如下两行:

  NLS_LANG=SIMPLIFIED Chinese_CHINA.ZHS16GBK    export NLS_LANG

  (2)客户端字符集与服务器端字符集相同,服务器端字符集与加载数据字符集不一致。这种情况一般发生在ORACLE版本升级或重新安装数据库时选择了与原来数据库不同的字符集,而恢复加载的备份数据仍是按原字符集卸出的场合。另一种情况是加载从其它使用不同字符集的ORACLE数据库卸出的数据。在这两种情况中,不管客户端字符集与服务器端字符集是否一致都无法正确显示汉字。具体解决方案:

  方案一:按服务端字符集的修改方法修改服务端字符集与加载数据字符集一致,然后导入数据。(见三中方法三)

  方案二:利用数据格式转储,避开字符集带来的问题。即先将加载数据倒入到与其字符集一致的数据库中,然后再将数据要么按文本格式导出(数据量较小的情况下),要么通过第三方工具(如POWER BUILDER,ACCESS,FOXPRO等)导出数据,最后将导出的数据导入到目标数据库中。

  (3)客户端字符集与服务器端字符集不同,服务端字符集与输入数据字符集不同。这种情况是在客户端字符集与服务器端字符集不一致时,从客户端输入了汉字信息。输入的这些信息即便是把客户端字符集更改正确,也无法显示汉字。解决方案:修改客户端字符集与服务端字符集一致后,重新输入数据。(此处较为复杂详情见百度文档)

  六、 总结

  由于ORACLE数据库创建后,数据库的字符集不能改变,因此需要提前考虑数据库将选用哪一种字符集,在我行中可以在ITA资源申请时关注相关情况。数据库字符集选择的一般规则是将数据库字符集设定为操作系统本地字符集的一个超集,同时数据库字符集也应该是所有客户字符集的超集。在中文环境中我们更多使用ZHS16GBK字符集,因为它包含了ZHS16CGB231280字符集,小伙伴们你们学会了么?


作者:林宫利    

来源:http://www.51testing.com/html/90/n-7801490.html

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 在当今的企业环境中,软件测试不再被视为不必要的投资;相反,它已经上升到一种需要而不是奢侈品的水平。随着市场的不断变化和竞争的加剧,企业必须做一些让他们与竞争对手区分开来的事情。为了使自己与众不同,公司必须提高效率、加速发展并以具有成本效益的方式提供质量。他们可以通过优秀的产品将他们的项目提升到一个新的水平。这增强了他们的潜在客户和当前客户对其产品的信赖,这可以通过强大的回归质量保证系统来实现。自动化测试是软件开发周期中最严格的软件测试,几乎每个组织都在使用它。自动化测试可以让公司以更快、更高质量的软件发布。测试自动化让测试人员从单调的任务中解脱出来,同时也加快了整个测试过程。然而,自动化的投资...
            0 0 874
            分享
          •   到底什么是接口呢?  我们先抛开IT层面的接口测试来说。回到生活中,我们想一下在生活中,我们有一些什么接口?生活中的接口就有很多。  比如说:插座、水龙头、转接头、充电器、usb、电源。  其实这个东西并没有那么难理解,接口在我们生活中间随处可见,我们想一下这些生活中的接口,他们的作用是什么?  比如说插座的话,是用来传电的,水龙头是来传水的。  转接头是用来拼接两头,然后进行物质的传输。  他们都有一个共同的特点,都是用来连接两个设备甚至是多个设备,并且进行物质之间的一个传递。  我们在生活中间的接口,就可以自己总结成一个这样简单的概念,对不对?  那其实,我们讲的软件测试中的接口和我们...
            0 0 1097
            分享
          • 环境配置是jmeter学习的第一步,每次换电脑就得重新配置,为了防止忘记,自己就整理了一下自己的设置方案。一、 JDK安装JMeter是 java 应用,所以需要 java 环境,下载 jdk 版本,当前推 荐 8, 下 载 链 接 : https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html安装 jdk,配置 jdk环境变量,参考链接:https://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3....
            1 1 1895
            分享
          •   Python获取当前文件路径以及父文件路径  #当前文件的路径   pwd = os.getcwd()   #当前文件的父路径   father_path=os.path.abspath(os.path.dirname(pwd)+os.path.sep+".")   #当前文件的前两级目录   grader_father=os.path.abspath(os.path.dirname(pwd)+os.path.sep+"..")   追加部分代码实例:      def TestP...
            0 0 943
            分享
          • 软件质量评估模型:顾名思义,软件质量评估模型是用来评估软件的测试质量的,也就是说测试的效果是否符合预期。 软件质量评估模型是从3个方面对软件质量进行评估的,内容如下所示: 1.测试覆盖度评估 2.测试过程评估 3.bug结果分析 测试覆盖度评估主要是对需求的覆盖范围进行评估的。测试过程评估主要是对测试用例的执行情况进行评估的。而bug结果分析主要是对bug的修复情况,bug的趋势分析进行评估的,下面我们就对这些详细的说明一下。 测试覆盖度评估 测试覆盖度评估是测试能够对软件质量进行评估的基础,如果覆盖度不够,那会对产品质量造成直接的影响。 测试覆盖度主要就是测试需求覆盖度的评估,需求覆盖度是已...
            3 8 6909
            分享
      • 51testing软件测试圈微信