精华内容
下载资源
问答
  •  Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,

    本文主要讨论以下几个部分:如何查看查询oracle字符集、 修改设置字符集以及常见的oracle utf8字符集和oracle exp 字符集问题。

    一、什么是Oracle字符集

           Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币,数字,和日历自动适应本地化语言和平台。

     

    影响Oracle数据库字符集最重要的参数是NLS_LANG参数。

    它的格式如下: NLS_LANG = language_territory.charset

    它有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。

    其中:

    Language: 指定服务器消息的语言, 影响提示信息是中文还是英文

    Territory: 指定服务器的日期和数字格式,

    Charset:  指定字符集。

    如:AMERICAN _ AMERICA. ZHS16GBK

    从NLS_LANG的组成我们可以看出,真正影响数据库字符集的其实是第三部分。

    所以两个数据库之间的字符集只要第三部分一样就可以相互导入导出数据,前面影响的只是提示信息是中文还是英文。

    怎么查看数据库版本

    select * from v$version   包含版本信息,核心版本信息,位数信息(32位或64位)等  至于位数信息,在Linux/unix平台上,可以通过file查看,如file $ORACLE_HOME/bin/oracle

     

    二、. 查看数据库字符集

    数据库服务器字符集select * from nls_database_parameters,其来源于props$,是表示数据库的字符集。

      

      客户端字符集环境select * from nls_instance_parameters,其来源于v$parameter,

      

      表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表

      

      会话字符集环境select * from nls_session_parameters,其来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是alter session完成,如果会话没有特殊的设置,将与nls_instance_parameters一致。

      

      客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。如果多个设置存在的时候,alter session>环境变量>注册表>参数文件

      

      字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是American_America.zhs16gbk。

     

    涉及三方面的字符集,

    1. oracel server端的字符集;

    2. oracle client端的字符集;

    3. dmp文件的字符集。

     

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

     

    2.1 查询oracle server端的字符集

    有很多种方法可以查出oracle server端的字符集,比较直观的查询方法是以下这种:

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

    USERENV('LANGUAGE')

    ----------------------------------------------------

    SIMPLIFIED CHINESE_CHINA.ZHS16GBK

     

    SQL>select userenv(‘language’) from dual;

    AMERICAN _ AMERICA. ZHS16GBK

     

    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

     

    如果dmp文件很大,比如有2G以上(这也是最常见的情况),用文本编辑器打开很慢或者完全打不开,可以用以下命令(在unix主机上):

    cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6

    然后用上述SQL也可以得到它对应的字符集。

     

    2.3 查询oracle client端的字符集

    在windows平台下,就是注册表里面相应OracleHome的NLS_LANG。还可以在dos窗口里面自己设置,

    比如: set nls_lang=AMERICAN_AMERICA.ZHS16GBK

    这样就只影响这个窗口里面的环境变量。

     

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

    $echo $NLS_LANG

    AMERICAN_AMERICA.ZHS16GBK

     

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

     

    补充:

    (1).数据库服务器字符集

    select * from nls_database_parameters

    来源于props$,是表示数据库的字符集。

     

    (2).客户端字符集环境

    select * from nls_instance_parameters

    其来源于v$parameter,表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表

     

    (3).会话字符集环境

    select * from nls_session_parameters

    来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是alter session完成,如果会话没有特殊的设置,将与nls_instance_parameters一致。

     

    (4).客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。

    如果多个设置存在的时候,NLS作用优先级别:Sql function > alter session > 环境变量或注册表> 参数文件> 数据库默认参数

     

    字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是American_America.zhs16gbk。

     

     

    三. 修改oracle的字符集

    8i以上版本可以通过alter database来修改字符集,但也只限于子集到超集,不建议修改props$表,将可能导致严重错误。

      

      Startup nomount;

      Alter database mount exclusive;

      Alter system enable restricted session;

      Alter system set job_queue_process=0;

      Alter database open;

      Alter database character set zhs16gbk;

    按照上文所说,数据库字符集在创建后原则上不能更改。因此,在设计和安装之初考虑使用哪一种字符集十分重要。对数据库server而言,错误的修改字符集将会导致很多不可测的后果,可能会严重影响数据库的正常运行,所以在修改之前一定要确认两种字符集是否存在子集和超集的关系。一般来说,除非万不得已,我们不建议修改oracle数据库server端的字符集。特别说明,我们最常用的两种字符集ZHS16GBK和ZHS16CGB231280之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持。

     

    不过修改字符集有2种方法可行。

    1. 通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换。

    2. 通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8是US7ASCII的超集,修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。

     

     

    3.1 修改server端字符集(不建议使用)

     

    1.       关闭数据库

    SQL>SHUTDOWN IMMEDIATE

     

    2. 启动到Mount

    SQL>STARTUP MOUNT;

    SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;

    SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;

    SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0;

    SQL>ALTER DATABASE OPEN;

    --这里可以从父集到子集

    SQL>ALTER DATABASE CHARACTER SET ZHS16GBK;

    SQL>ALTER DATABASE NATIONAL CHARACTER SET AL16UTF16;

    --如果是从子集到父集,需要使用INTERNAL_USE 参数,跳过超子集检测

    SQL>ALTER DATABASE CHARACTER SET INTERNAL_USE AL32UTF8;

    SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE AL16UTF16;

     

    SQL>SHUTDOWN IMMEDIATE;

    SQL>STARTUP

    注意:如果没有大对象,在使用过程中进行语言转换没有什么影响,(切记设定的字符集必须是ORACLE支持,不然不能start) 按上面的做法就可以。

     

    若出现‘ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when NCLOB data exists’ 这样的提示信息,

    要解决这个问题有两种方法

    1. 利用INTERNAL_USE 关键字修改区域设置,

    2. 利用re-create,但是re-create有点复杂,所以请用internal_use

     

    SQL>SHUTDOWN IMMEDIATE;

    SQL>STARTUP MOUNT EXCLUSIVE;

    SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;

    SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;

    SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0;

    SQL>ALTER DATABASE OPEN;

    SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8;

    SQL>SHUTDOWN immediate;

    SQL>startup;

    如果按上面的做法做,National charset的区域设置就没有问题

     

    3.2 修改dmp文件字符集

    上文说过,dmp文件的第2第3字节记录了字符集信息,因此直接修改dmp文件的第2第3字节的内容就可以‘骗’过oracle的检查。这样做理论上也仅是从子集到超集可以修改,但很多情况下在没有子集和超集关系的情况下也可以修改,我们常用的一些字符集,如US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK基本都可以改。因为改的只是dmp文件,所以影响不大。

     

    具体的修改方法比较多,最简单的就是直接用UltraEdit修改dmp文件的第2和第3个字节。

    比如想将dmp文件的字符集改为ZHS16GBK,可以用以下SQL查出该种字符集对应的16进制代码: SQL> select to_char(nls_charset_id('ZHS16GBK'), 'xxxx') from dual;

    0354

    然后将dmp文件的2、3字节修改为0354即可。

    如果dmp文件很大,用ue无法打开,就需要用程序的方法了。

     

    3.3客户端字符集设置方法

         1)UNIX环境

             $NLS_LANG=“simplified chinese”_china.zhs16gbk

             $export NLS_LANG

             编辑oracle用户的profile文件

        2)Windows环境

             编辑注册表

             Regedit.exe ---》HKEY_LOCAL_MACHINE ---》SOFTWARE ---》ORACLE-HOME

      或者在窗口设置:

            set nls_lang=AMERICAN_AMERICA.ZHS16GBK

    四.字符集的相关知识:

    4.1 字符集

        实质就是按照一定的字符编码方案,对一组特定的符号,分别赋予不同数值编码的集合。Oracle数据库最早支持的编码方案是US7ASCII。

        Oracle的字符集命名遵循以下命名规则:

        <Language><bit size><encoding>

        即: <语言><比特位数><编码>

        比如: ZHS16GBK表示采用GBK编码格式、16位(两个字节)简体中文字符集

     

    4.2 字符编码方案

     

    4.2.1 单字节编码

        (1)单字节7位字符集,可以定义128个字符,最常用的字符集为US7ASCII

        (2)单字节8位字符集,可以定义256个字符,适合于欧洲大部分国家

                 例如:WE8ISO8859P1(西欧、8位、ISO标准8859P1编码)

     

    4.2.2 多字节编码

        (1)变长多字节编码

        某些字符用一个字节表示,其它字符用两个或多个字符表示,变长多字节编码常用于对亚洲语言的支持,   例如日语、汉语、印地语等

        例如:AL32UTF8(其中AL代表ALL,指适用于所有语言)、zhs16cgb231280

        (2)定长多字节编码

        每一个字符都使用固定长度字节的编码方案,目前oracle唯一支持的定长多字节编码是AF16UTF16,也是仅用于国家字符集

    4.2.3 unicode编码

        Unicode是一个涵盖了目前全世界使用的所有已知字符的单一编码方案,也就是说Unicode为每一个字符提供唯一的编码。UTF-16是unicode的16位编码方式,是一种定长多字节编码,用2个字节表示一个unicode字符,AF16UTF16是UTF-16编码字符集。

        UTF-8是unicode的8位编码方式,是一种变长多字节编码,这种编码可以用1、2、3个字节表示一个unicode字符,AL32UTF8,UTF8、UTFE是UTF-8编码字符集

     

    4.3 字符集超级

        当一种字符集(字符集A)的编码数值包含所有另一种字符集(字符集B)的编码数值,并且两种字符集相同编码数值代表相同的字符时,则字符集A是字符集B的超级,或称字符集B是字符集A的子集。

        Oracle8i和oracle9i官方文档资料中备有子集-超级对照表(subset-superset pairs),例如:WE8ISO8859P1是WE8MSWIN1252的子集。由于US7ASCII是最早的Oracle数据库编码格式,因此有许多字符集是US7ASCII的超集,例如WE8ISO8859P1、ZHS16CGB231280、ZHS16GBK都是US7ASCII的超集。

     

    4.4 数据库字符集(oracle服务器端字符集)

        数据库字符集在创建数据库时指定,在创建后通常不能更改。在创建数据库时,可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。

     

    4.4.1字符集

        (1)用来存储CHAR, VARCHAR2, CLOB, LONG等类型数据

        (2)用来标示诸如表名、列名以及PL/SQL变量等

        (3)用来存储SQL和PL/SQL程序单元等

     

    4.4.2国家字符集:

        (1)用以存储NCHAR, NVARCHAR2, NCLOB等类型数据

        (2)国家字符集实质上是为oracle选择的附加字符集,主要作用是为了增强oracle的字符处理能力,因为NCHAR数据类型可以提供对亚洲使用定长多字节编码的支持,而数据库字符集则不能。国家字符集在oracle9i中进行了重新定义,只能在unicode编码中的AF16UTF16和UTF8中选择,默认值是AF16UTF16

     

    4.4.3查询字符集参数

        可以查询以下数据字典或视图查看字符集设置情况

        nls_database_parameters、props$、v$nls_parameters

        查询结果中NLS_CHARACTERSET表示字符集,NLS_NCHAR_CHARACTERSET表示国家字符集

     

    4.4.4修改数据库字符集

        按照上文所说,数据库字符集在创建后原则上不能更改。不过有2种方法可行。

     

    1. 如果需要修改字符集,通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换。

    2. 通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8是US7ASCII的超集,修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。

     

    4.5 客户端字符集(NLS_LANG参数)

     

    4.5.1客户端字符集含义

        客户端字符集定义了客户端字符数据的编码方式,任何发自或发往客户端的字符数据均使用客户端定义的字符集编码,客户端可以看作是能与数据库直接连接的各种应用,例如sqlplus,exp/imp等。客户端字符集是通过设置NLS_LANG参数来设定的。

     

    4.5.2 NLS_LANG参数格式

        NLS_LANG=<language>_<territory>.<client character set>

        Language: 显示oracle消息,校验,日期命名

        Territory:指定默认日期、数字、货币等格式

        Client character set:指定客户端将使用的字符集

        例如:NLS_LANG=AMERICAN_AMERICA.US7ASCII

        AMERICAN是语言,AMERICA是地区,US7ASCII是客户端字符集

     

    4.5.3客户端字符集设置方法

         1)UNIX环境

             $NLS_LANG=“simplified chinese”_china.zhs16gbk

             $export NLS_LANG

             编辑oracle用户的profile文件

        2)Windows环境

             编辑注册表

             Regedit.exe ---》HKEY_LOCAL_MACHINE ---》SOFTWARE ---》ORACLE-HOME

     

    4.5.4 NLS参数查询

        Oracle提供若干NLS参数定制数据库和用户机以适应本地格式,例如有NLS_LANGUAGE,NLS_DATE_FORMAT,NLS_CALENDER等,可以通过查询以下数据字典或v$视图查看。

    NLS_DATABASE_PARAMETERS:显示数据库当前NLS参数取值,包括数据库字符集取值

    NLS_SESSION_PARAMETERS:  显示由NLS_LANG 设置的参数,或经过alter session 改变后的参数值(不包括由NLS_LANG 设置的客户端字符集)

    NLS_INSTANCE_PARAMETE: 显示由参数文件init<SID>.ora 定义的参数

    V$NLS_PARAMETERS:显示数据库当前NLS参数取值

     

    4.5.5修改NLS参数

        使用下列方法可以修改NLS参数

        (1)修改实例启动时使用的初始化参数文件

        (2)修改环境变量NLS_LANG

        (3)使用ALTER SESSION语句,在oracle会话中修改

        (4)使用某些SQL函数

        NLS作用优先级别:Sql function > alter session > 环境变量或注册表> 参数文件> 数据库默认参数

     

    五.EXP/IMP 与 字符集

    5.1 EXP/IMP

        Export 和Import 是一对读写Oracle数据的工具。Export 将Oracle 数据库中的数据输出到操作系统文件中, Import 把这些文件中的数据读到Oracle 数据库中,由于使用exp/imp进行数据迁移时,数据从源数据库到目标数据库的过程中有四个环节涉及到字符集,如果这四个环节的字符集不一致,将会发生字符集转换。

    EXP

         ____________ _________________ _____________

         |imp导入文件|<-|环境变量NLS_LANG|<-|数据库字符集|

          ------------   -----------------   -------------

    IMP

         ____________ _________________ _____________

         |imp导入文件|->|环境变量NLS_LANG|->|数据库字符集|

          ------------   -----------------   -------------

     

     

    四个字符集是

       (1)源数据库字符集

       (2)Export过程中用户会话字符集(通过NLS_LANG设定)

       (3)Import过程中用户会话字符集(通过NLS_LANG设定)

       (4)目标数据库字符集

     

    5.2导出的转换过程

        在Export过程中,如果源数据库字符集与Export用户会话字符集不一致,会发生字符集转换,并在导出文件的头部几个字节中存储Export用户会话字符集的ID号。在这个转换过程中可能发生数据的丢失。

     

    例:如果源数据库使用ZHS16GBK,而Export用户会话字符集使用US7ASCII,由于ZHS16GBK是16位字符集,而US7ASCII是7位字符集,这个转换过程中,中文字符在US7ASCII中不能够找到对等的字符,所以所有中文字符都会丢失而变成“?? ”形式,这样转换后生成的Dmp文件已经发生了数据丢失。

    因此如果想正确导出源数据库数据,则Export过程中用户会话字符集应等于源数据库字符集或是源数据库字符集的超集

     

    5.3导入的转换过程

        (1)确定导出数据库字符集环境

                 通过读取导出文件头,可以获得导出文件的字符集设置

        (2)确定导入session的字符集,即导入Session使用的NLS_LANG环境变量

        (3)IMP读取导出文件

                 读取导出文件字符集ID,和导入进程的NLS_LANG进行比较

        (4)如果导出文件字符集和导入Session字符集相同,那么在这一步骤内就不需要转换,             如果不同,就需要把数据转换为导入Session使用的字符集。可以看出,导入数据到数据库过程中发生两次字符集转换

     

        第一次:导入文件字符集与导入Session使用的字符集之间的转换,如果这个转换过程不能正确完成,Import向目标数据库的导入过程也就不能完成。

        第二次:导入Session字符集与数据库字符集之间的转换。

    展开全文
  • 字符集它涉及到很的东西 比如建库和操作系统环境 这节课把字符集的原理性的东西以及常见的操作讲一下 大家以后不要在字符集方面犯一些错误 以后字符集的问题基本都可以解决了 一)字符集的发展 通过查找各...

    Oracle 学习笔记 字符集概述

    这节课开始讲oracle里面的字符集
    偏重于原理和简单的一些判断以及实现

    字符集它涉及到很多的东西
    比如建库和操作系统环境

    这节课把字符集的原理性的东西以及常见的操作讲一下
    大家以后不要在字符集方面犯一些错误
    以后字符集的问题基本都可以解决了

    一)字符集的发展

    通过查找各方面资料
    这里把字符集的发展自己先简单梳理了一下

    字符集是编号和字符的对应表
    是为了让计算机使用和显示出来人们使用的语言和符号
    这个编号就是编码表中的编码
    而字符的表现都是字模的形式
    一个编码对应着一个图形类型的字模
    人们向计算机输入字符,计算机通过编码表把它转变为编码
    这些编码在计算机内部处理或运算
    而需要查看处理过程和结果的时候
    因为有了这种编码就可以从这些编码表中找到对应的字模
    并有系统绘制或显示出来

    计算机控制运算和传输只能使用二进制的1和0
    要输入和显示出的文字和符号都要有一个转变为0、1和由0、1转变来的过程
    这样就需要用二进制来标定它们
    计算机需要使用编码表来完成这个工作

    在地球上
    计算机使用最早的字符集是
    BCD(binary coded decimal)编码表
    只有十个数据
    用二进制表示从0到9十个数字
    只要四位二进制就够了

    这些对计算机是不够的
    因为计算机还要使用字母和控制符

    而恰好计算机最早出现在使用英语的美国

    所以IBM公司(国际商用机器公司)制定了EBCDIC编码
    EBCDIC码(Extended Binary Coded Decimal Interchange Code)
    广义二进制编码的十进制交换码
    对BCD码扩展
    使用八位二进制表示256个包括数字、英文字符、控制符和其它一些常用字符

    这时美国国家标准局(ANSI)也制定了ASCII码
    即美国标准信息交换码(American Standard Code for Information Interchange)
    被国际标准化组织( International Organization for Standardization, ISO )批准为国际标准
    称为ISO 646标准

    基本的 ASCII 字符集,使用了七位二进制,共有 128 个字符,
    其中有 96 个可打印字符,包括常用的字母、数字、标点符号等,另外还有 32 个控制字符

    EBCDIC和ASCII中都主要是英文字母,但在字符的位置和排列顺序上不一样

    在计算机技术发展的早期,如ASCII和EBCDIC这样的字符集逐渐成为标准

    数字0到9使用BCD编码4位的二进制就可以实现
    英文字符、控制符和一些常用的符号用7位二进制的标准ASCII可以完成

    但是世界上的符号包括文字非常的多
    各个国家都要使用计算机
    就需要更多的二进制数来和他们对应

    首先字母文字国家把这种编码表扩充到了8位

    ISO 陆续制定了一批适用于不同地区的扩充 ASCII 字符集
    最低的128个代码总是相同的,较高的128个代码取决于定义内码表的语言

    这多余的128个码位的不同扩展,就形成了一系列ISO-8859-*的标准

    代表性的是实现了西欧语言编码的ISO-8859-1(即Latin-1)
    它向下兼容ASCII,是一种西欧字符集

    像东亚的国家
    每个文字都是一个独立的符号
    用8位只256个空间无法表示
    所以位数被进一步扩展
    使用了16位二进制为自己的国家制定了编码表
    用于显示本国的语言
    不同的国家和地区制定了不同的标准,
    由此产生了 GB2312, BIG5, JIS 等各自的编码标准
    它们使用2个字节来代表一个字符

    每个字符使用一个字节编码,这样的字符集就是单字节字符集SBCS(Single-byte Character Sets)
    每个字符最多使用两个字节编码,这样的字符集就是双字节字符集DBCS(Double-byte Character Sets)
    某些字符的编码超过了一个字节,这样的字符集就是多字节字符集MBCS(Multi-byte Character Sets)

    在中国,中国国家标准委员会开始了设计工作
    保留ASCII的127号以前的编码并把编码扩展到两个字节
    方案中可以组合出大约7000多个中文字符,这就是国标(国家标准GB)2312
    是中国国家标准简体中文字符集,全称《信息交换用汉字编码字符集·基本集》,又称GB0

    GB2312 是对 ASCII 的中文扩展
    由于GB2312只收录6763个汉字,于是微软利用GB 2312未使用的编码空间,制定了GBK编码
    GBK即汉字内码扩展规范
    K为汉语拼音 Kuo Zhan(扩展)中“扩”字的声母
    英文全称Chinese Internal Code Specification
    也使用了双字节编码方案。

    在香港出现了Big5,又称大五码
    是繁体中文(正体中文)最常用字符集标准,共收录13060个汉字

    这些出现的由ASCII扩展而来,用于单种语言的编码表又被微软使用为ANSI编码
    在简体中文系统下,ANSI 编码代表 GB2312 编码,
    在日文操作系统下,ANSI 编码代表 JIS 编码
    它们既兼容ASCII又互相不兼容

    这时世界已形成出了多种的字符编码体系
    包括分别以ASCII和EBCDIC为基础并且由它们扩展而来的编码体系
    还有SAP(systems applications and products in data processing)体系等
    SAP在德国,是全球企业管理软件与解决方案的技术领袖,同时也是市场领导者
    SAP既是公司名称,又是其产品企业管理解决方案的软件名称

    每种编码体系都有各种文字的很多的编码表
    但是各自的编码不同,适用于不同的环境
    EBCDIC编码体系主要由IBM生产的机器使用,
    如IBM的大型机S/390、zSeries及其上的操作系统IBMOS/390、z/OS
    和IBM的中小型机AS/400、IBM i系列及其上的操作系统OS/400、i5/OS
    IBM的个人计算机和工作站操作系统使用的是文本的工业标准编码ASCII码
    如:AIX(Advanced Interactive eXecutive)IBM开发的一套UNIX操作系统
    它的平台的字符编码是基于 ASCII 的

    一般地说,开放的操作系统(LINUX 、WINDOWS等)采用ASCII 编码,
    而大型主机系统(MVS 、OS/390)等采用EBCDIC 编码。
    绝大多数所熟悉的系统都是使用ASCII

    在每个体系中还存在一个问题
    各个语言的编码表自己独立使用是可以的
    如果放在一起使用会发生同一编码对应不同文字的冲突问题

    为了解决这个问题
    一个软件制造商的协会unicode组织和国际标准化组织(ISO)
    都进行了把世界上所有的字符放在一起进行统一编码的工作
    ISO开发了ISO 10646项目,Unicode协会开发了Unicode项目

    Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案
    而Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容)

    “ Universal Multiple-Octet Coded Character Set”,简称UCS
    是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集

    当双方认识到世界不需要两个不兼容的字符集
    它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作

    从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码
    ISO也承诺使两方保持一致
    目前两个项目仍都存在,并独立地公布各自的标准。

    UCS编码有自己的格式:UCS-2和UCS-4等等
    在编码层面上
    UCS-2就是用两个字节编码
    UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码。

    unicode在编码上和UCS保持一致,在实现上有自己的规则,而UCS只定义了编码标准。

    unicode的实现形式上有UTF-8,UTF-16,UTF-32,还有UTF-7等。
    UTF是“UCS Transformation Format”的缩写
    都是将数字转换到程序数据的编码方案。

    UTF-16是UCS-2的扩展,UTF-32是UCS-4的子集。

    一般对于UNICODE来说,UCS-2是内码,而UTF-8等则是它的实现方式

    中国为了和ISO 10646编码接轨制定了国家标准GB13000
    等同于国际标准的《通用多八位编码字符集 (UCS)》 ISO10646.1
    就是等同于Unicode的标准,代码页等等的都使用UTF的一套标准
    一共使用四个字节
    目前所有字符代码的前两个字节都是0
    因此默认情况下按照两字节处理

    而GBK并非国家正式标准
    仅是GB 2312到GB 13000.1-93之间的过渡方案

    但GB13000标准目前发展缓慢

    GB 18030全称:国家标准GB 18030-2005《信息技术中文编码字符集》
    是中华人民共和国现时最新的内码字集
    GB 18030与GB 2312-1980完全兼容,与GBK基本兼容,支持GB 13000及Unicode的全部统一汉字,
    共收录汉字70244个
    与 UTF-8 相同,采用多字节编码,每个字可以由1个、2个或4个字节组成

    GB18030是我国继GB2312-1980和GB13000-1993之后最重要的汉字编码标准,
    是未来我国计算机系统必须遵循的基础性标准之一

    在windows中这些编码表被称为代码页,也称为“内码表”

    早期,代码页是IBM称呼计算机的BIOS所支持的字符集编码
    操作系统直接使用BIOS提供的字符绘制功能来显示字符(或者是一组嵌入在显卡字符生成器中的字形)
    操作系统的编码支持也就依靠BIOS的编码
    这时的代码页被集成在硬件中,由制造商选择集成哪种代码页,称作OEM(原始设备制造商)代码页
    最具代表性的是”IBM PC或MS-DOS 代码页437”。

    随着图形用户界面操作系统的广泛使用,操作系统本身具有了字符绘制的功能
    Windows代码页最初是根据ANSI草案实现的
    微软在Windows操作系统没有转向UTF-16作为内码实现之前(也就是在Windows 2000之前),
    针对不同的使用地区与国家,定义了一系列的支持不同语言字符集的代码页,
    被称作”Windows(或ANSI)代码页”。
    这是Windows代码页被称作ANSI的缘由。
    ANSI由ASCII标准编码扩展而来,它们既兼容ASCII又互相不兼容

    ANSI code pages实际上是一系列的编码集合,
    是微软自己定义的代码页
    根据操作系统区域设置而激活其中一种作为ANSI编码由系统默认使用。
    在保存文件时编码选择ANSI就是选择这个默认的编码。
    公司电脑(英文系统)上的ANSI code page可能是1252,而家里的中文系统则可能是936
    在简体中文操作系统中ANSI编码默认指的是GB系列编码(GB2312、GBK);
    在繁体中文操作系统中ANSI编码默认指的是BIG5;
    在日文操作系统中ANSI编码默认指的是Shift JIS

    ANSI编码是在Windows中特别是在windows安装过程中可以指定为默认代码页
    为了使windows系统本地化而选择的一种本地语言编码表
    由于世界上有很多的语种,
    每种语言的ANSI编码指的都是这种语言对应的编码表,国家不同代码页也不同
    在windows中同时只能选择一种代码页作为ANSI编码使用

    ANSI代码页的特点:
    编码0至127符合ANSI制定的ASCII编码标准
    是由微软制定并实现的
    编码最多两个字节

    ANSI使用最明显的例子:
    widows中保存文本文件一般
    里面有四个选项:ANSI,Unicode,Unicode big endian 和 UTF-8

    (1)ANSI是默认的编码方式。
    对于英文文件是ASCII编码,对于简体中文文件是GB2312编码
    (只针对Windows简体中文版,如果是繁体中文版会采用Big5码)。
    (2)Unicode编码指的是UCS-2编码方式,即直接用两个字节存入字符的Unicode码。
    这个选项用的little endian格式。
    (3)Unicode big endian编码与上一个选项相对应。
    (4)UTF-8编码
    它们就是windows系统正在使用的字符集
    第一个选项就是使用的系统默认的ANSI代码页

    在windows中的代码页是微软系统使用的当然要由微软指定
    对于ANSI编码微软往往都是先得到相应国家自己制定的标准
    然后微软对其进行修改或扩充得到自己的代码页

    如繁体中文的BIG5编码,日本的Shift JIS编码,西欧iso-8859-1
    微软以原编码为基础
    对其修改扩充后分别得到的代码页编号为950,932,1252

    简体中文GBK码
    是微软在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案
    完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,
    并包含了BIG5编码中的所有汉字
    GBK对应代码页936

    Windows平台上的GUI程序使用ANSI代码页,
    而控制台程序Windows 中的字符模式的应用程序(使用命令提示符窗口的应用程序)
    使用过去在 DOS 中使用的代码页。
    由于历史原因,这些代码页称为 OEM(原始设备制造商)代码页
    这两种代码页在前128个字符的编码是一样的,
    但后128个字符的编码可能不一致。
    而现在图形系统中提供的OEM代码页只是为了和早期使用OEM代码页的程序兼容

    字符要在系统中绘制
    还需要字符编码表对应的字模库,也称字形库
    计算机最早使用的是点阵字体字模,
    到现在有了很多的矢量字体字模,又称轮廓字体、描边字体,
    TrueType字体与PostScript字体、OpenType字体是主要的三种

    点阵字体也叫位图字体,其中每个字形都以一组二维像素信息表示
    矢量字库保存的是对每一个字的描述信息
    比较而言点阵字体优点是显示速度快,最大的缺点是不能放大
    现在点阵字体仍在被广泛的使用

    Windows使用的字库也为以上两类,
    在FONTS目录下,如果字体扩展名为FON,表示该文件为点阵字库,扩展名为TTF则表示矢量字库

    下面简单的列一下windows中几个代码页和字符集的对应关系

    分三列,分别表示
    代码页编号、对应编码名称、说明
    37 IBM037 IBM EBCDIC (US-Canada) 就是最早的EBCDIC编码表
    437 IBM437 OEM United States 美国扩展ASCII表,最初的IBM PC代碼頁,实现了扩展ASCII字符集
    20127 us-ascii US-ASCII 就是基础的7位ASCII编码

    65000 utf-7 Unicode (UTF-7)
    65001 utf-8 Unicode (UTF-8)
    65005 utf-32LE Unicode (UTF-32)
    65006 utf-32BE Unicode (UTF-32 Big-Endian)

    1200 UTF-16LE Unicode(UCS-2LE Unicode) (little-endian小端序)
    1201 UTF-16BE Unicode(UCS-2BE Unicode) (big-endian大端序)

    20936 GB2312 简体中文(GB2312)
    936 GBK 简体中文(GBK)
    54936 GB18030 简体中文(GB18030)
    950 BIG5 繁體中文(大五碼)
    932 Shift_JIS 日文(Shift_JIS)
    949 EUC-KR 韓文(EUC-KR)

    28591 iso-8859-1 西欧字符 (ISO)Latin-1 西歐拉丁字母
    28605 iso-8859-15 Latin 9 (ISO) 西欧语言
    1252 Windows-1252 西欧字符(Windows)

    有个别情况要说明:

    Windows 1252和ISO 8859-1基本等同但并不完全一致,
    ISO-8859-1在0x80-0x9F范围的控制字符,在Windows-1252中被可打印字符取代。
    由于在web网页中,ASCII控制字符不起作用,
    所以网页一般用Windows-1252代码页标记替代ISO-8859-1标记。

    iso-8859-15 Latin 9 字符集是iso-8859-1 Latin 1字符集的更新版本,
    去掉一些不常用的字符,增加修正了部分字符,增加了欧元字符

    每种编码集在不同的编码体系中有不同的别名

    如iso-8859-1编码:
    ISO-8859-1编码也是单字节编码,最多能够表示256个字符。
    Latin1是ISO-8859-1的别名,有些环境下写作Latin-1
    在OEM(IBM PC)代码页编号是 850 —“多语言(Latin-1)” (西欧语言)
    IBM中叫它Code page 819 or CP819
    Oracle中则是WE8ISO8859P1编码或WE8MSWIN1252编码
    SAP中是SAP Code page 1100
    在windows中被使用为28591和1252代码页

    又如UTF-8:
    UTF-8在IBM称作代码页1208,在微软称作代码页65001,在SAP称作代码页4110

    在oracle中对编码的命名有一定的规则
    如:

    AL32UTF8

    【AL】支持所有语言(All Language)。

    【32】每字符最多占用32位(4字节)。

    【UTF8】编码为UTF-8。

    WE8MSWIN1252

    【WE】支持西欧语言(Western Europe)。

    【8】每字符需要占用8位(单字节)。

    【MSWIN1252】编码为CP1252。

    US7ASCII

    【US】表示美国(United States)。

    【7】每字符需要占用7位。

    【ASCII】编码为ASCII。

    其它如ZHS16GBK,ZHT16BIG5,US8PC437(编码为OEM cp437),都可以类推

    二)字符集概念

    继续讲课课程

    首先看一下
    oracle的字符集,什么叫字符集

    字符集说白了是一个集合
    是一张表,这个表有两列

    左面这列是字符是所有要存储的字符

    字符有很多字符
    比如我们讲中文字符
    左面这列就是中国人常用的所有的中文字符
    有汉字、英文字母有数字还有一些特殊的符号
    在左面都出现是我们中文要使用的所有的字符
    右边是一个编码,从1号2、3、4、5、6
    将来提到1的时候就对应着一个字符

    所以说字符集就是字符和编码的这么一个对应表

    我们知道在计算机里面只能存储数字
    我们不能存储一个字符,存储不了字符

    但是我们还想在计算机里面存储字符
    我们就做了一件事情
    将字符对应成编码存储起来

    比如我要存中文
    中文里面的“中国”这两个字符
    我们就找这个字符集
    “中”和“国”分别对应着两个编码
    把两个编码存储到数据库里面去
    这是存储的时候

    显示的时候
    根据两个编码再来查
    显示的是”中”和”国”
    把两个字符显示出来
    这就是我们计算机里面的字符集的概念

    在计算机里面很多地方都有字符集的概念
    我们的oracle数据库也有字符集的概念

    因为oracle要存字符
    有字符就需要字符集的概念

    三)有字符集的地方

    简单讲一下哪些地方有字符集

    1)操作系统

    第一个操作系统有字符集
    比如我们的windows有字符集
    linux也有字符集,unix也有字符集
    操作系统os本身有字符集

    比如我们的linux字符集我们可以看一下
    使用locale命令

    [oracle@redhat4 ~]$ locale
    LANG=zh_CN.UTF-8
    LC_CTYPE="zh_CN.UTF-8"
    LC_NUMERIC="zh_CN.UTF-8"
    LC_TIME="zh_CN.UTF-8"
    LC_COLLATE="zh_CN.UTF-8"
    LC_MONETARY="zh_CN.UTF-8"
    LC_MESSAGES="zh_CN.UTF-8"
    LC_PAPER="zh_CN.UTF-8"
    LC_NAME="zh_CN.UTF-8"
    LC_ADDRESS="zh_CN.UTF-8"
    LC_TELEPHONE="zh_CN.UTF-8"
    LC_MEASUREMENT="zh_CN.UTF-8"
    LC_IDENTIFICATION="zh_CN.UTF-8"
    LC_ALL=

    这个命令结果中
    当前的字符集是UTF-8

    还有locale 加上 -a 参数

    [oracle@redhat4 ~]$ locale -a
    aa_DJ
    aa_DJ.iso88591
    aa_DJ.utf8
    aa_ER
    aa_ER@saaho
    aa_ER.utf8
    aa_ER.utf8@saaho
    aa_ET
    aa_ET.utf8
    .
    .
    .
    zh_CN
    zh_CN.gb18030
    zh_CN.gb2312
    zh_CN.gbk
    zh_CN.utf8
    zh_HK
    zh_HK.big5hkscs
    zh_HK.utf8
    zh_SG
    zh_SG.gb2312
    zh_SG.gbk
    zh_SG.utf8
    zh_TW
    zh_TW.big5
    zh_TW.euctw
    zh_TW.utf8
    zu_ZA
    zu_ZA.iso88591
    zu_ZA.utf8

    结果内容较多只列出一部分
    可以展示出linux支持的所有的字符集

    还支持zh_HK.big5hkscs
    大5码,香港人用的

    还支持zh_SG.gbk
    我们的国标

    还支持zh_TW.utf8
    UNICODE类字符集

    这里有它支持的所有字符集

    在windows里面支持的当前的字符集

    先打开 windows 的 命令提示符
    有一个chcp命令

    C:\WINDOWS>chcp
    活动的代码页: 936

    活动代码页是936
    936是中文字符集

    这是我们操作系统有字符集

    2)oracle数据库

    oracle数据库本身有字符集
    数据库软件里面带着字符集

    它也带着很多张表
    一个表是一种字符集

    字符集可以认为是一张表
    是一张字符和编码的对应表

    oracle有字符集说明oracle有这张表

    oracle支持很多种字符集说明oracle里面有很多种这张表

    操作系统有字符集也有这张表

    3)软件

    还有一些软件跟oracle一样
    本身也带字符集

    有些软件本身是不带字符集的
    有些软件有字符集

    oracle或者一些别的软件有字符集
    他就自己使用自己的
    有些软件不带字符集的字符集
    他就使用操作系统字符集

    要注意这个地方
    看看软件本身有没有字符集

    后面还会通过例子去强调

    字符集就是字符和编码的这么一张对应表
    操作系统和oracle都有字符集的概念

    四)什么时候用字符集

    我们访问一个表
    访问t2这张表

    先把t2中的数据都删了

    SQL> delete from t2;
    
    1 row deleted.
    
    SQL> commit;
    
    Commit complete.

    先查一下

    SQL> select * from t2;
    
    no rows selected

    没有数据

    SQL> desc t2;
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     ID                                                 NUMBER
     NAME                                               VARCHAR2(20)

    t2这张表有两个列
    一个是ID列 类型是NUMBER 数字列
    NAME列 是VARCHAR2列 VARCHAR是字符

    所以说对这个表来讲
    表t2有两列
    有id列类型是number
    name列类型是varchar

    对id列来讲,因为它是数字列,没有字符的概念
    对这个列来讲不用字符集

    往这个列中插入数据和删除数据、显示数据的时候
    它不涉及到字符的概念字符集的概念

    但是name列 类型是varchar 或varchar2
    因为这个列存储的是字符

    往这个列中插入删除还有显示数据的时候
    这个列要用到字符集的概念
    如果一个数据库里面没有varchar
    只有类似于number这样的这种列
    这个数据库可以没有字符集的概念

    但大家想想没有可能,不可能
    所有的数据库里面的表总有varchar
    而且还以varchar为主

    什么时候使用字符集呢

    (1)当我们用来存储CHAR, VARCHAR2, CLOB, LONG等类型数据的时候

    这四种类型都是放字符的
    char是固定长度放字符的
    varchar是可变长度放字符的
    clob是大对象,比如我们把一片文章存进去
    long也是大对象,但它现在像是慢慢被clob取代了

    当我们的列是这四种列的时候
    往这四种列存数据的时候用到字符集

    当然了还有数据字典里面
    (2)用来标示诸如表名、列名以及PL/SQL变量等
    (3)用来存储SQL和PL/SQL程序单元等

    数据字典里面的一些char和varchar,clob和long也要用到数据库字符集

    五)国家字符集

    还有一种用到的字符集

    我们在oracle安装的时候
    有两个字符集
    一个是数据库字符集
    一个是国家字符集

    看一下我们oracle安装过程的时候
    在其中安装的一步的时候
    在调sga、pga里面
    我们还可以看到有字符集的选择
    我们有两种字符集
    第一是数据库字符集,我们选择了
    第二是国家字符集,我们也选择了

    这两个字符集含义
    是分别应用在不同场合

    当我们建立一个表
    这个表如果它的列的类型是char varchar clob long
    这个时候oracle就使用数据库字符集

    如果我们建了一个表
    它的数据类型是 nchar nvarchar2 或nclob
    这个时候针对这个表我们就使用国家字符集

    现在表t2它的有个列是varchar
    我往t2插入数据和显示数据的时候
    它会用到数据库字符集

    再建立一个表t3

    SQL> create table t3(id number,name nvarchar2(20));
    
    Table created.

    这是建了一个表

    SQL> desc t3;
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     ID                                                 NUMBER
     NAME                                               NVARCHAR2(20)

    这个时候针对表t3它的列是nvarchar

    对表t3来讲
    我要能往里面存储数据和显示数据的时候
    用到国家字符集

    向t3表中插入数据

    SQL> insert into t3 values(1,'中国');
    
    1 row created.

    查看使用的字符集

    SQL> select id,name,dump(name,1016) from t3;
    
            ID NAME   DUMP(NAME,1016)
    ---------- ------ --------------------------------------------------
             1 中国   Typ=1 Len=4 CharacterSet=AL16UTF16: 4e,2d,56,fd

    可以看出CharacterSet=AL16UTF16
    这里说明是使用的国家字符集

    一个表中同时存在varchar和nvarchar时
    就是即使用数据库字符集又使用国家字符集时
    国家字符集的设置只对nvarchar的列起作用

    新建一个表t4,包含varchar列和nvarchar列

    SQL> create table t4(id number,name varchar(20),namen nvarchar2(20));
    
    Table created.
    
    SQL> desc t4;
     Name    Null?    Type
     ------- -------- --------------------------------------------------------
     ID                NUMBER
     NAME              VARCHAR2(20)
     NAMEN             NVARCHAR2(20)

    向t4中插入数据

    SQL> insert into t4 values(1,'中国','中国');
    
    1 row created.

    查看数据的编码

    SQL> select id,name,dump(name,1016),namen,dump(namen,1016) from t4;
    
            ID NAME   DUMP(NAME,1016)                                    NAMEN  DUMP(NAMEN,1016)
    ---------- ------ -------------------------------------------------- ------ --------------------------------------------------
             1 中国   Typ=1 Len=4 CharacterSet=ZHS16GBK: d6,d0,b9,fa     中国   Typ=1 Len=4 CharacterSet=AL16UTF16: 4e,2d,56,fd

    可以看出varchar列使用的数据库字符集ZHS16GBK
    而nvarchar列使用的是国家字符集AL16UTF16

    所以国家字符集不是作用于整个表
    而是作用于使用它的列

    六)数据库字符集状况

    我们可以查一下数据库用到字符集的状况

    SQL> select * from nls_database_parameters;
    
    PARAMETER                      VALUE
    ------------------------------ ----------------------------------------
    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 TZR
    NLS_TIMESTAMP_TZ_FORMAT        DD-MON-RR HH.MI.SSXFF AM TZR
    NLS_DUAL_CURRENCY              $
    NLS_COMP                       BINARY
    NLS_LENGTH_SEMANTICS           BYTE
    NLS_NCHAR_CONV_EXCP            FALSE
    NLS_NCHAR_CHARACTERSET         AL16UTF16
    NLS_RDBMS_VERSION              10.2.0.1.0
    
    20 rows selected.

    数据库的字符集
    NLS_CHARACTERSET ZHS16GBK
    是中文字符集
    目前数据库的字符集是中文字符集

    国家字符集是
    NLS_NCHAR_CHARACTERSET AL16UTF16

    数据库里面是两个字符集
    第一叫数据库字符集
    第二叫国家字符集

    当前数据库系统使用环境
    数据库字符集是中文字符集
    国家字符集是AL16UTF16

    通过
    select * from nls_database_parameters;
    这个sql语句可以查出来

    一般来讲国家字符集用的比较少
    一般都是使用数据库字符集
    国家字符集往往作为数据库字符集的一个补充
    它们应用场合不同

    七)常用字符集

    讲到这个地方我们看一下字符集的命名

    比如对oracle数据库来讲
    有几个经典的字符集

    经常关注
    US7ASCII
    ZHS16CGB231280
    AL32UTF8
    AF16UTF16
    ZHS16GBK
    utf8
    这几个字符集

    我们关注字符集的时候其实就关注一个地方
    这个字符集能存储哪些字符

    比如这个US7ASCII码
    这是美国人使用的字符集
    它只能存储美国人的使用的字符
    美国人存储使用的字符不超过128个

    我们学计算机的时候
    学ascii码都知道
    我们的ascii码一共使用一个字节8个位来表示
    对美国人来讲它只使用右边的7位,最高位是0
    所以说它只使用7位

    只能存储常见的26个英文字母数字
    以及加减乘除等字符
    不超过128个
    这是美国人用的字符集US7ASCII

    zhs16cgb231280是中国人用的字符集
    里面可以存中文
    这是我们的中文的国标
    这个字符集比较老
    里面并没有存储所有的中文字符集,相对少一些

    最新的中文字符集是ZHS16GBK
    我们都用这个最新的中文字符集

    zhs16cgb231280这个字符集所容纳的所有的字符
    ZHS16GBK都有
    也就是说ZHS16GBK是zhs16cgb231280的超集

    超集不意味着严格超集

    所谓的超集就是
    zhs16cgb231280里面有的字符
    ZHS16GBK里面都有是超集

    严格超集是
    zhs16cgb231280里面有的字符
    ZHS16GBK里面都有
    而且zhs16cgb231280里面字符对应的编码
    和ZHS16GBK里面对应的编码是一样的
    这就是严格超集

    比如说zhs16cgb231280和ZHS16GBK是超集的关系
    但不是严格超集的关系

    比如“中国”两个字
    在zhs16cgb231280有,在ZHS16GBK里面也有
    但是在zhs16cgb231280里面的编码
    和在ZHS16GBK里面的编码是不一样的
    所以只能说是超集不能说是严格超集

    这是中文

    还有一个utf8字符集
    叫unicode字符集

    zhs16cgb231280和ZHS16GBK这两个里面存的是中国人常用的字符
    US7ASCII存的是美国人常用的字符

    比如说“中石油”,这是个跨国企业
    有一张表专门存储员工的姓名的
    对中石油来讲
    它既有中国人也有韩国人也有日本人也有津巴布韦非洲人
    有很多员工
    这些员工的名字是有各个国家的名字
    它们有自己的语言

    所以说这个表里面现在有一个需求

    数据库里面
    有张表,有列
    有一个列是varchar将来可以存字符
    存字符要用到数据库字符集

    这里面将来要存储的
    第一存储中文,第二英文,第三日文,第四韩语
    要存储很多字符集字符

    要用中文字符集不行
    英文字符集不行
    日文韩文都不行
    针对日文韩文都有相关的字符集都不行

    这个时候针对这个问题
    有一些比较大的公司它们统一起来做了一张字符集
    叫unicode字符集
    当时它设计的初衷是
    将全世界所有的字符以及对应的编码编成一个字符集

    unicode字符集也是字符集
    左面是字符右面是编码

    只不过它左边的字符不仅仅局限于中文英文
    它的初衷是把全世界所有的字符全部编到这个编码里面去
    然后给它统一性编码
    也就是说如果说数据库是unicode字符集的话
    也就意味着它可以存储全世界所有的字符

    所以一开始推出了一个utf8,u开头的字符集

    因为当时基于技术以及各个方面的限制
    这个utf8它的初衷是存储全部的字符
    但是并没有做到
    只是存储了部分字符集
    但是里面有中英文日文都有
    只不过没有那么全而已

    utf8是一个比较老的unicode字符集

    最后随着技术的改进
    又推出了AL32UTF8这个最新的字符集
    这个字符集比utf8字符就多的多了
    它含的字符集范围就非常广了

    所以说要用unicode字符集的话那就用AL32UTF8

    对国家字符集来讲我们统一的选AF16UTF16
    这个字符集也是unicode字符集

    unicode字符集有三个
    AL32UTF8
    AF16UTF16
    utf8

    对数据库字符集来讲,我们通常选择AL32UTF8
    对国家字符集来讲,我们选择AF16UTF16

    因为AL32UTF8是unicode最新字符集
    AF16UTF16是数据库国家字符集

    八)存储中文的选择

    如果一个数据库里面我们将来要存中文
    有几种选择

    对国家字符集来讲
    我们只选择AF16UTF16没有别的选择

    对数据库字符集来讲
    如果我将来要存中文有两种办法

    第一种办法
    我们将数据库字符集设成AL32UTF8
    将来存中文肯定没问题

    第二个办法
    做成ZHS16GBK

    如果确认数据库里面将来只存中文当然里面也包括英文
    只存中英文
    也就是说只是中国人使用
    最好把它设成ZHS16GBK

    AL32UTF8它里面是可以存中文
    但是每一个中文所对应的字符编码会消耗更多的空间
    也就是说AL32UTF8它全,但是在性能上会差一些
    考虑到性能我们最好用ZHS16GBK

    如果存中文,如果只存中文那就是ZHS16GBK

    如果你是国际化、国际型的企业那就是UTF8

    选择AL32UTF8的话在很多地方会涉及到字符编码的转换
    以及占用过多的空间
    占用过多的空间就意味着
    将来io啊网络啊等等会有更大的负载

    这就是数据库字符集该如何选择

    US7ASCII中的US表示语言存的是英语
    7是也就是将来编码是用7位
    ASCII是编码

    对我们中国人来讲
    将来用ZHS16GBK用16位,GBK表示国标,
    是使用我们中国人,我们的中文国标来进行编码

    九)有多少字符集可以选择

    我们到底有多少字符集可以选择
    可以使用
    select * from V$NLS_VALID_VALUES;
    看一下

    SQL> select * from V$NLS_VALID_VALUES;
    
    PARAMETER       VALUE                     ISDEP
    --------------- ------------------------- -----
    LANGUAGE        AMERICAN                  FALSE
    LANGUAGE        GERMAN                    FALSE
    LANGUAGE        FRENCH                    FALSE
    LANGUAGE        CANADIAN FRENCH           FALSE
    .
    .
    .                 
    LANGUAGE        THAI                      FALSE
    LANGUAGE        JAPANESE                  FALSE
    LANGUAGE        KOREAN                    FALSE
    LANGUAGE        SIMPLIFIED CHINESE        FALSE
    LANGUAGE        TRADITIONAL CHINESE       FALSE
    LANGUAGE        ENGLISH                   FALSE
    .
    .
    .
    TERRITORY       AMERICA                   FALSE
    TERRITORY       UNITED KINGDOM            FALSE
    .
    .
    .                 
    TERRITORY       UNITED ARAB EMIRATES      FALSE
    TERRITORY       THAILAND                  FALSE
    TERRITORY       CHINA                     FALSE
    TERRITORY       HONG KONG                 FALSE
    TERRITORY       JAPAN                     FALSE
    TERRITORY       KOREA                     FALSE
    TERRITORY       TAIWAN                    FALSE
    .
    .
    .            FALSE
    CHARACTERSET    US7ASCII                  FALSE
    CHARACTERSET    WE8DEC                    FALSE
    .
    .
    .            
    CHARACTERSET    WE8PC858                  FALSE
    CHARACTERSET    WE8ISO8859P1              FALSE
    CHARACTERSET    EE8ISO8859P2              FALSE
    CHARACTERSET    SE8ISO8859P3              FALSE
    CHARACTERSET    NEE8ISO8859P4             FALSE
    CHARACTERSET    CL8ISO8859P5              FALSE
    CHARACTERSET    AR8ISO8859P6              FALSE
    CHARACTERSET    EL8ISO8859P7              FALSE
    CHARACTERSET    IW8ISO8859P8              FALSE
    CHARACTERSET    WE8ISO8859P9              FALSE
    CHARACTERSET    NE8ISO8859P10             FALSE
    .
    .
    .            
    CHARACTERSET    IW8MSWIN1255              FALSE
    CHARACTERSET    LT8MSWIN921               FALSE
    CHARACTERSET    TR8MSWIN1254              FALSE
    CHARACTERSET    WE8MSWIN1252              FALSE
    .
    .
    . 
    CHARACTERSET    JA16VMS                   FALSE
    CHARACTERSET    JA16EUC                   FALSE
    CHARACTERSET    JA16EUCYEN                FALSE
    CHARACTERSET    JA16SJIS                  FALSE
    CHARACTERSET    JA16DBCS                  FALSE
    CHARACTERSET    JA16SJISYEN               FALSE
    CHARACTERSET    JA16EBCDIC930             FALSE
    CHARACTERSET    JA16MACSJIS               FALSE
    CHARACTERSET    JA16EUCTILDE              FALSE
    CHARACTERSET    JA16SJISTILDE             FALSE
    CHARACTERSET    KO16KSC5601               FALSE
    CHARACTERSET    KO16DBCS                  FALSE
    CHARACTERSET    KO16KSCCS                 FALSE
    CHARACTERSET    KO16MSWIN949              FALSE            
    CHARACTERSET    ZHS16CGB231280            FALSE
    CHARACTERSET    ZHS16MACCGB231280         FALSE
    CHARACTERSET    ZHS16GBK                  FALSE
    CHARACTERSET    ZHS16DBCS                 FALSE
    CHARACTERSET    ZHS32GB18030              FALSE
    CHARACTERSET    ZHT32EUC                  FALSE
    CHARACTERSET    ZHT32SOPS                 FALSE
    CHARACTERSET    ZHT16DBT                  FALSE
    CHARACTERSET    ZHT32TRIS                 FALSE
    CHARACTERSET    ZHT16DBCS                 FALSE
    CHARACTERSET    ZHT16BIG5                 FALSE
    CHARACTERSET    ZHT16CCDC                 FALSE
    CHARACTERSET    ZHT16MSWIN950             FALSE
    CHARACTERSET    ZHT16HKSCS                FALSE
    CHARACTERSET    AL24UTFFSS                TRUE
    CHARACTERSET    UTF8                      FALSE
    CHARACTERSET    UTFE                      FALSE
    CHARACTERSET    AL32UTF8                  FALSE
    CHARACTERSET    ZHT16HKSCS31              FALSE
    CHARACTERSET    JA16EUCFIXED              TRUE
    CHARACTERSET    JA16SJISFIXED             TRUE
    CHARACTERSET    JA16DBCSFIXED             TRUE
    CHARACTERSET    KO16KSC5601FIXED          TRUE
    CHARACTERSET    KO16DBCSFIXED             TRUE
    CHARACTERSET    ZHS16CGB231280FIXED       TRUE
    CHARACTERSET    ZHS16GBKFIXED             TRUE
    CHARACTERSET    ZHS16DBCSFIXED            TRUE
    CHARACTERSET    ZHT32EUCFIXED             TRUE
    CHARACTERSET    ZHT32TRISFIXED            TRUE
    CHARACTERSET    ZHT16DBCSFIXED            TRUE
    CHARACTERSET    ZHT16BIG5FIXED            TRUE
    CHARACTERSET    AL16UTF16                 FALSE
    .
    .
    .
    SORT            TCHINESE_RADICAL_M        FALSE
    SORT            BIG5                      FALSE
    SORT            HKSCS                     FALSE
    SORT            TCHINESE_STROKE_M         FALSE
    SORT            SCHINESE_PINYIN_M         FALSE
    SORT            SCHINESE_STROKE_M         FALSE
    SORT            GBK                       FALSE
    SORT            SCHINESE_RADICAL_M        FALSE
    SORT            JAPANESE_M                FALSE
    SORT            KOREAN_M                  FALSE
    
    494 rows selected.

    返回内容较多只截取了部分显示

    第一列是LANGUAGE的部分
    如:
    LANGUAGE AMERICAN FALSE
    这是字符集关于语言的设置

    第一列是CHARACTERSET
    如:
    CHARACTERSET US7ASCII FALSE
    是关于字符集的设计

    结果中有非常多的字符集可以设置
    全部都可以设

    有oracle支持的所有的字符集

    有CHARACTERSET AL16UTF16 FALSE
    字符集
    是最后面的一个字符集

    还有
    CHARACTERSET AL32UTF8 FALSE
    这个字符集unicode字符集

    中文字符集可以去找一下

    CHARACTERSET ZHS16GBK FALSE
    是中文字符集

    还有一些日文字符集
    如:
    CHARACTERSET JA16SJISTILDE FALSE

    除了我们中英文以外
    还有一些字符集
    以后做数据库的时候经常会碰到
    就是我们的繁体

    繁体字符集里面又分台湾的和香港的
    香港的都用大5码

    因为现在的我们的台湾企业和香港企业很多
    所以说你将来毕业以后如果去香港企业的话
    你会发现它的字符集很多用大5码
    大5码是繁体中文
    存简体中文的时候可能有问题

    在返回结果中的第三列是ISDEPRECATED
    中文翻译是:是否被启用
    就是因为版本升级的原因,有些参数可能在新版本中已不再被使用
    如果当前还被使用这个值是FALSE
    如果当前版本已经不使用这个参数了,这个值就是true

    记住这里有一个视图可以去查

    这里讲了数据库字符集的一些常见的一些知识
    以及常见字符集一些基础的知识
    并讲了相关的视图
    同时讲了哪些字符集可以设置

    字符集的概论先简单讲到这个地方
    下节课讲一下
    在一个复杂的环境里面我们该如何去设置字符集
    以及出了字符集以后如何去判断

    十)操作系统

    字符集是操作系统处理信息的一个很重要的方面
    操作系统到底是什么这里也简单的说一下

    人们在运行各种软件时
    基本都不是在硬件上直接运行
    而是在操作系统上运行

    它给了一个操作计算机的环境
    使硬件合理正确的工作
    给软件提供运行的环境

    一个好的操作系统
    可以全面的控制硬件
    并使硬件完成各种各样的功能
    不用每个软件再去编码完成同样的事情

    它本身和软件和硬件都有紧密的结合

    以硬件和集成在硬件上的更基础的软件为基础如各种bios
    给程序提供各种运行的需求

    bios为基本输入输出系统,为计算机中最基础的系统
    它集成在硬件中并最直接的和硬件接触

    计算机启动需要先启动硬件
    从主机加电开始
    然后检查各个硬件,使硬件的bios运行

    而操作系统一般在硬盘中
    接着主板上的bios找到硬盘上的操作系统

    如果一切正常操作系统就开始运行,启动成功了

    计算机和操作系统历史都很悠久
    已经有很多的成功产品
    每类产品都包含了很多的内容

    一般的操作系统都是针对某一类硬件制作的
    在提供给某一类软件运行环境时
    也给软件在其上运行产生了无法避免的限制

    一种系统产生的目的大多是给某类的软件提供运行环境
    同时也决定了它的使用群也是固定的
    大型企业要使用服务器而一般家庭使用pc机就可以了

    操作系统也通过编写代码实现
    任何人代码编写都有自己的目的也都是想实现自己的目的

    在人们印象中计算机最大的特点是它的自动化的执行方法
    程序代码可以一行行的自动运行
    功能的运行也以这种自动为主
    但是关键的操作部分还是需要人的操控
    这种关键的控制部分操作系统控制了最关键的部分

    程序完成的自动功能是有范围的
    不可能完成一些人们想象中的很多种的自动功能
    尽管理论上是可以实现的,但很多只是个幻想
    因为计算机作为一种人类的产品能够做的工作也是有限的

    系统的发展是一个不断修改和完善的过程

    现在的操作系统都已包含了非常多的内容并形成了体系
    对硬件的使用趋于完善

    对原系统修改形成新的系统
    人们的愿望是使其进步

    修改原系统就要自己编写代码和修改别人的代码
    自己编写代码都有自己的目的
    修改别人的代码也会同时修改了别人的意图

    这种修改在事实上产生了两种后果

    系统有些方面好用了 和 系统有些方面产生了新的限制

    对软件也产生了两个方面的作用
    软件更好用了和破坏了软件原来的运行环境

    这是因为要进行修改
    就要使原系统使用自己选择的技术

    必然要修改或舍弃一部分原有内容
    就会影响到整个系统的稳定和软件对它使用的要求
    虽然有可能得到好的结果
    但是这么庞大的代码中
    坏的影响也同样的不可避免

    如果你的技术做到了只对原有系统有好的改进
    那绝对是一个好的技术
    但是这是很难做到的
    每个成熟系统都已经经过了很多的这样的进步
    一个不全面了解原代码的程序员
    是很难得到这样的结果的

    计算机硬件的改变在计算机发展过程中非常常见
    所有的系统都是根据硬件编写的,并只适用于特定的硬件
    如果原有计算机使用的硬件基础改变了
    对操作系统的影响将是巨大的
    因为它在整个系统的最底层
    哪怕只是小小的改变也会引起一系列的影响
    这样就需要系统全面的改变
    或者选择不影响系统的硬件方法

    更何况引进的一种硬件本身未必有什么好的用处
    或者原有系统根本无法使用它

    为了避免这种种冲突,
    最好的办法应该是
    系统制造者自己选择自己的硬件,自己编写自己的系统

    对使用者来说每个人需要的系统中的内容不会是一样的
    个人自主选择操作系统来使用是使用系统的方法

    操作系统是非常重要的
    要根据个人的情况选择、使用、修改或者创新

    十一)总结查询和设置字符集的命令

    1)查看当前字符集

    windows的注册表中
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\下
    ACP值为目前的GUI代码页

    windows系统命令提示符可使用chcp命令

    linux系统使用locale命令返回当前字符集信息

    locale -a 可以查询linux系统支持的所有字符集

    oracle数据库查nls_database_parameters
    使用select * from nls_database_parameters;
    语句得到数据库字符集信息
    使用SELECT * FROM v$nls_parameters;
    得到当前会话的字符集信息

    操作系统和数据库使用的字符集是系统或oracle安装时选择的
    不建议去改动它
    数据库字符集虽然可以强行更改
    但要求新字符集必须是原字符集的超集
    否则会产生严重的错误如数据库无法启动或数据库中数据损坏

    2)设置NLS_LANG参数

    windows系统级永久更改NLS_LANG
    可以更改注册表或环境变量

    regedit进入注册表

    NLS_LANG的位置
    版本 8 , 8i and 9i:
    HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMExx\
    “x”为定义Oracle home的唯一值

    版本 10g 及以上:
    HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_

    在这个位置可以修改NLS_LANG选项的值
    注册表HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE路径只要在操作系统安装了oracle才有

    windows 我的电脑->属性->高级->环境变量
    在系统或者用户变量设置NLS_LANG

    linux系统级别永久更改NLS_LANG
    也可以更改环境变量

    在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效

    linux用户级别
    可以编辑用户的 bash_profile 文件进行永久设置
    vi .bash_profile
    NLS_LANG=”Simplified Chinese_china”.ZHS16GBK export NLS_LANG
    重启系统
    或者执行 source .bash_profile
    使 bash_profile 设置立即生效
    这个设置在使用此用户登陆的所有会话中有效

    临时更改
    就是会话级别的更改,变量在关闭shell时失效

    windows系统shell中
    使用set命令
    如:
    set NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

    linux系统shell中
    使用export命令
    如:
    export NLS_LANG=”SIMPLIFIED CHINESE_CHINA.ZHS16GBK”

    在shell中这样的更改只在这一个shell中有效

    3)查看NLS_LANG

    windows的shell中

    set NLS_LANG
    echo %NLS_LANG%

    linux的shell中

    env | grep NLS_LANG
    echo $NLS_LANG

    sqlplus软件中执行shell命令也可以查看NLS_LANG

    如果sqlplus运行在windows的shell中
    在命令前加上$或host

    如果sqlplus运行在linux的shell中
    在命令前要加上!或host

    如sqlplus在window的shell中:

    SQL> $ echo %NLS_LANG%
    SIMPLIFIED CHINESE_CHINA.ZHS16GBK
    
    SQL> host echo %NLS_LANG%
    SIMPLIFIED CHINESE_CHINA.ZHS16GBK
    
    SQL> host set NLS_LANG
    NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
    
    SQL> $ set NLS_LANG
    NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

    如sqlplus在linux的shell中:

    SQL> host echo $NLS_LANG
    SIMPLIFIED CHINESE_CHINA.ZHS16GBK
    
    SQL> ! echo $NLS_LANG
    SIMPLIFIED CHINESE_CHINA.ZHS16GBK
    
    SQL> host env | grep NLS_LANG
    NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
    
    SQL> ! env | grep NLS_LANG
    NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

    字符集在oracle中使用是很复杂的
    有很多关联的数据字典或视图
    用几行文字难以说清,可慢慢在使用中熟悉

    2017年10月22日
    文字:韵筝

    展开全文
  • 本文主要讨论以下几个部分:... Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,
    本文主要讨论以下几个部分:如何查看查询oracle字符集、 修改设置字符集以及常见的oracle utf8字符集和oracle exp 字符集问题。
    


    一、什么是Oracle字符集


           Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币,数字,和日历自动适应本地化语言和平台。


    影响Oracle数据库字符集最重要的参数是NLS_LANG参数。


    它的格式如下: NLS_LANG = language_territory.charset


    它有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。


    其中:


    Language: 指定服务器消息的语言, 影响提示信息是中文还是英文


    Territory: 指定服务器的日期和数字格式,


    Charset:  指定字符集。


    如:AMERICAN _ AMERICA. ZHS16GBK


    从NLS_LANG的组成我们可以看出,真正影响数据库字符集的其实是第三部分。


    所以两个数据库之间的字符集只要第三部分一样就可以相互导入导出数据,前面影响的只是提示信息是中文还是英文。


    怎么查看数据库版本


    select * from v$version   包含版本信息,核心版本信息,位数信息(32位或64位)等  至于位数信息,在Linux/unix平台上,可以通过file查看,如file $ORACLE_HOME/bin/oracle


    二、. 查看数据库字符集


    数据库服务器字符集select * from nls_database_parameters,其来源于props$,是表示数据库的字符集。


      客户端字符集环境select * from nls_instance_parameters,其来源于v$parameter,


      表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表 


      会话字符集环境select * from nls_session_parameters,其来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是alter session完成,如果会话没有特殊的设置,将与nls_instance_parameters一致。


      客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。如果多个设置存在的时候,alter session>环境变量>注册表>参数文件


      字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是American_America.zhs16gbk。


    涉及三方面的字符集,


    1. oracel server端的字符集;


    2. oracle client端的字符集;


    3. dmp文件的字符集。


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


    2.1 查询oracle server端的字符集


    有很多种方法可以查出oracle server端的字符集,比较直观的查询方法是以下这种:


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


    USERENV('LANGUAGE')


    ----------------------------------------------------


    SIMPLIFIED CHINESE_CHINA.ZHS16GBK


    SQL>select userenv(‘language’) from dual;


    AMERICAN _ AMERICA. ZHS16GBK


    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


    如果dmp文件很大,比如有2G以上(这也是最常见的情况),用文本编辑器打开很慢或者完全打不开,可以用以下命令(在unix主机上):


    cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6


    然后用上述SQL也可以得到它对应的字符集。




    2.3 查询oracle client端的字符集


    在windows平台下,就是注册表里面相应OracleHome的NLS_LANG。还可以在dos窗口里面自己设置,


    比如: set nls_lang=AMERICAN_AMERICA.ZHS16GBK


    这样就只影响这个窗口里面的环境变量。


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


    $echo $NLS_LANG


    AMERICAN_AMERICA.ZHS16GBK


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


    补充:


    (1).数据库服务器字符集


    select * from nls_database_parameters


    来源于props$,是表示数据库的字符集。


    (2).客户端字符集环境


    select * from nls_instance_parameters


    其来源于v$parameter,表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表


    (3).会话字符集环境


    select * from nls_session_parameters


    来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是alter session完成,如果会话没有特殊的设置,将与nls_instance_parameters一致。


    (4).客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。


    如果多个设置存在的时候,NLS作用优先级别:Sql function > alter session > 环境变量或注册表> 参数文件> 数据库默认参数


    字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是American_America.zhs16gbk。
     


    三. 修改oracle的字符集


    8i以上版本可以通过alter database来修改字符集,但也只限于子集到超集,不建议修改props$表,将可能导致严重错误。


      Startup nomount;


      Alter database mount exclusive;


      Alter system enable restricted session;


      Alter system set job_queue_process=0;


      Alter database open;


      Alter database character set zhs16gbk;


    按照上文所说,数据库字符集在创建后原则上不能更改。因此,在设计和安装之初考虑使用哪一种字符集十分重要。对数据库server而言,错误的修改字符集将会导致很多不可测的后果,可能会严重影响数据库的正常运行,所以在修改之前一定要确认两种字符集是否存在子集和超集的关系。一般来说,除非万不得已,我们不建议修改oracle数据库server端的字符集。特别说明,我们最常用的两种字符集ZHS16GBK和ZHS16CGB231280之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持。


    不过修改字符集有2种方法可行。


    1. 通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换。


    2. 通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8是US7ASCII的超集,修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。




    3.1 修改server端字符集(不建议使用)


    1.       关闭数据库


    SQL>SHUTDOWN IMMEDIATE


    2. 启动到Mount


    SQL>STARTUP MOUNT;


    SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;


    SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;


    SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0;


    SQL>ALTER DATABASE OPEN;


    --这里可以从父集到子集


    SQL>ALTER DATABASE CHARACTER SET ZHS16GBK;


    SQL>ALTER DATABASE NATIONAL CHARACTER SET AL16UTF16;


    --如果是从子集到父集,需要使用INTERNAL_USE 参数,跳过超子集检测


    SQL>ALTER DATABASE CHARACTER SET INTERNAL_USE AL32UTF8;


    SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE AL16UTF16;


    SQL>SHUTDOWN IMMEDIATE;


    SQL>STARTUP


    注意:如果没有大对象,在使用过程中进行语言转换没有什么影响,(切记设定的字符集必须是ORACLE支持,不然不能start) 按上面的做法就可以。


    若出现‘ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when NCLOB data exists’ 这样的提示信息,


    要解决这个问题有两种方法


    1. 利用INTERNAL_USE 关键字修改区域设置,


    2. 利用re-create,但是re-create有点复杂,所以请用internal_use




    SQL>SHUTDOWN IMMEDIATE;


    SQL>STARTUP MOUNT EXCLUSIVE;


    SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;


    SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;


    SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0;


    SQL>ALTER DATABASE OPEN;


    SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8;


    SQL>SHUTDOWN immediate;


    SQL>startup;


    如果按上面的做法做,National charset的区域设置就没有问题




    3.2 修改dmp文件字符集


    上文说过,dmp文件的第2第3字节记录了字符集信息,因此直接修改dmp文件的第2第3字节的内容就可以‘骗’过oracle的检查。这样做理论上也仅是从子集到超集可以修改,但很多情况下在没有子集和超集关系的情况下也可以修改,我们常用的一些字符集,如US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK基本都可以改。因为改的只是dmp文件,所以影响不大。


    具体的修改方法比较多,最简单的就是直接用UltraEdit修改dmp文件的第2和第3个字节。


    比如想将dmp文件的字符集改为ZHS16GBK,可以用以下SQL查出该种字符集对应的16进制代码: SQL> select to_char(nls_charset_id('ZHS16GBK'), 'xxxx') from dual;


    0354


    然后将dmp文件的2、3字节修改为0354即可。


    如果dmp文件很大,用ue无法打开,就需要用程序的方法了。


    3.3客户端字符集设置方法


         1)UNIX环境


             $NLS_LANG=“simplified chinese”_china.zhs16gbk


             $export NLS_LANG


             编辑oracle用户的profile文件


        2)Windows环境


             编辑注册表


             Regedit.exe ---》HKEY_LOCAL_MACHINE ---》SOFTWARE ---》ORACLE-HOME


      或者在窗口设置:


            set nls_lang=AMERICAN_AMERICA.ZHS16GBK


    四.字符集的相关知识:


    4.1 字符集


        实质就是按照一定的字符编码方案,对一组特定的符号,分别赋予不同数值编码的集合。Oracle数据库最早支持的编码方案是US7ASCII。


        Oracle的字符集命名遵循以下命名规则:


        <Language><bit size><encoding>


        即: <语言><比特位数><编码>


        比如: ZHS16GBK表示采用GBK编码格式、16位(两个字节)简体中文字符集




    4.2 字符编码方案


    4.2.1 单字节编码


        (1)单字节7位字符集,可以定义128个字符,最常用的字符集为US7ASCII


        (2)单字节8位字符集,可以定义256个字符,适合于欧洲大部分国家
    例如:WE8ISO8859P1(西欧、8位、ISO标准8859P1编码)




    4.2.2 多字节编码


        (1)变长多字节编码


        某些字符用一个字节表示,其它字符用两个或多个字符表示,变长多字节编码常用于对亚洲语言的支持,   例如日语、汉语、印地语等


        例如:AL32UTF8(其中AL代表ALL,指适用于所有语言)、zhs16cgb231280


        (2)定长多字节编码


        每一个字符都使用固定长度字节的编码方案,目前oracle唯一支持的定长多字节编码是AF16UTF16,也是仅用于国家字符集


    4.2.3 unicode编码


        Unicode是一个涵盖了目前全世界使用的所有已知字符的单一编码方案,也就是说Unicode为每一个字符提供唯一的编码。UTF-16是unicode的16位编码方式,是一种定长多字节编码,用2个字节表示一个unicode字符,AF16UTF16是UTF-16编码字符集。


        UTF-8是unicode的8位编码方式,是一种变长多字节编码,这种编码可以用1、2、3个字节表示一个unicode字符,AL32UTF8,UTF8、UTFE是UTF-8编码字符集


    4.3 字符集超级


        当一种字符集(字符集A)的编码数值包含所有另一种字符集(字符集B)的编码数值,并且两种字符集相同编码数值代表相同的字符时,则字符集A是字符集B的超级,或称字符集B是字符集A的子集。


        Oracle8i和oracle9i官方文档资料中备有子集-超级对照表(subset-superset pairs),例如:WE8ISO8859P1是WE8MSWIN1252的子集。由于US7ASCII是最早的Oracle数据库编码格式,因此有许多字符集是US7ASCII的超集,例如WE8ISO8859P1、ZHS16CGB231280、ZHS16GBK都是US7ASCII的超集。


    4.4 数据库字符集(oracle服务器端字符集)


        数据库字符集在创建数据库时指定,在创建后通常不能更改。在创建数据库时,可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。


    4.4.1字符集


        (1)用来存储CHAR, VARCHAR2, CLOB, LONG等类型数据


        (2)用来标示诸如表名、列名以及PL/SQL变量等


        (3)用来存储SQL和PL/SQL程序单元等


    4.4.2国家字符集:


        (1)用以存储NCHAR, NVARCHAR2, NCLOB等类型数据


        (2)国家字符集实质上是为oracle选择的附加字符集,主要作用是为了增强oracle的字符处理能力,因为NCHAR数据类型可以提供对亚洲使用定长多字节编码的支持,而数据库字符集则不能。国家字符集在oracle9i中进行了重新定义,只能在unicode编码中的AF16UTF16和UTF8中选择,默认值是AF16UTF16


    4.4.3查询字符集参数


        可以查询以下数据字典或视图查看字符集设置情况


        nls_database_parameters、props$、v$nls_parameters


        查询结果中NLS_CHARACTERSET表示字符集,NLS_NCHAR_CHARACTERSET表示国家字符集


    4.4.4修改数据库字符集


        按照上文所说,数据库字符集在创建后原则上不能更改。不过有2种方法可行。
    1. 如果需要修改字符集,通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换。


    2. 通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8是US7ASCII的超集,修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。


    4.5 客户端字符集(NLS_LANG参数)


    4.5.1客户端字符集含义


        客户端字符集定义了客户端字符数据的编码方式,任何发自或发往客户端的字符数据均使用客户端定义的字符集编码,客户端可以看作是能与数据库直接连接的各种应用,例如sqlplus,exp/imp等。客户端字符集是通过设置NLS_LANG参数来设定的。


    4.5.2 NLS_LANG参数格式


        NLS_LANG=<language>_<territory>.<client character set>


        Language: 显示oracle消息,校验,日期命名


        Territory:指定默认日期、数字、货币等格式


        Client character set:指定客户端将使用的字符集


        例如:NLS_LANG=AMERICAN_AMERICA.US7ASCII


        AMERICAN是语言,AMERICA是地区,US7ASCII是客户端字符集


    4.5.3客户端字符集设置方法


         1)UNIX环境


             $NLS_LANG=“simplified chinese”_china.zhs16gbk


             $export NLS_LANG


             编辑oracle用户的profile文件


        2)Windows环境


             编辑注册表


             Regedit.exe ---》HKEY_LOCAL_MACHINE ---》SOFTWARE ---》ORACLE-HOME


    4.5.4 NLS参数查询


        Oracle提供若干NLS参数定制数据库和用户机以适应本地格式,例如有NLS_LANGUAGE,NLS_DATE_FORMAT,NLS_CALENDER等,可以通过查询以下数据字典或v$视图查看。


    NLS_DATABASE_PARAMETERS:显示数据库当前NLS参数取值,包括数据库字符集取值


    NLS_SESSION_PARAMETERS:  显示由NLS_LANG 设置的参数,或经过alter session 改变后的参数值(不包括由NLS_LANG 设置的客户端字符集)


    NLS_INSTANCE_PARAMETE: 显示由参数文件init<SID>.ora 定义的参数


    V$NLS_PARAMETERS:显示数据库当前NLS参数取值


    4.5.5修改NLS参数


        使用下列方法可以修改NLS参数


        (1)修改实例启动时使用的初始化参数文件


        (2)修改环境变量NLS_LANG


        (3)使用ALTER SESSION语句,在oracle会话中修改


        (4)使用某些SQL函数


        NLS作用优先级别:Sql function > alter session > 环境变量或注册表> 参数文件> 数据库默认参数


    五.EXP/IMP 与 字符集


    5.1 EXP/IMP


        Export 和Import 是一对读写Oracle数据的工具。Export 将Oracle 数据库中的数据输出到操作系统文件中, Import 把这些文件中的数据读到Oracle 数据库中,由于使用exp/imp进行数据迁移时,数据从源数据库到目标数据库的过程中有四个环节涉及到字符集,如果这四个环节的字符集不一致,将会发生字符集转换。


    EXP
         ____________ _________________ _____________


         |imp导入文件|<-|环境变量NLS_LANG|<-|数据库字符集|


          ------------   -----------------   -------------


    IMP
         ____________ _________________ _____________


         |imp导入文件|->|环境变量NLS_LANG|->|数据库字符集|


          ------------   -----------------   -------------
    四个字符集是


       (1)源数据库字符集


       (2)Export过程中用户会话字符集(通过NLS_LANG设定)


       (3)Import过程中用户会话字符集(通过NLS_LANG设定)


       (4)目标数据库字符集


    5.2导出的转换过程


    在Export过程中,如果源数据库字符集与Export用户会话字符集不一致,会发生字符集转换,并在导出文件的头部几个字节中存储Export用户会话字符集的ID号。在这个转换过程中可能发生数据的丢失。


    例:如果源数据库使用ZHS16GBK,而Export用户会话字符集使用US7ASCII,由于ZHS16GBK是16位字符集,而US7ASCII是7位字符集,这个转换过程中,中文字符在US7ASCII中不能够找到对等的字符,所以所有中文字符都会丢失而变成“?? ”形式,这样转换后生成的Dmp文件已经发生了数据丢失。


    因此如果想正确导出源数据库数据,则Export过程中用户会话字符集应等于源数据库字符集或是源数据库字符集的超集


    5.3导入的转换过程


        (1)确定导出数据库字符集环境


    通过读取导出文件头,可以获得导出文件的字符集设置


        (2)确定导入session的字符集,即导入Session使用的NLS_LANG环境变量


        (3)IMP读取导出文件


    读取导出文件字符集ID,和导入进程的NLS_LANG进行比较


        (4)如果导出文件字符集和导入Session字符集相同,那么在这一步骤内就不需要转换,             
    如果不同,就需要把数据转换为导入Session使用的字符集。可以看出,导入数据到数据库过程中发生两次字符集转换


        第一次:导入文件字符集与导入Session使用的字符集之间的转换,如果这个转换过程不能正确完成,Import向目标数据库的导入过程也就不能完成。


        第二次:导入Session字符集与数据库字符集之间的转换。
    展开全文
  • 我们知道在导出文件中,记录着导出使用的字符集id,通过查看导出文件头的第2、3个字节,我们可以找到16进制表示的字符集ID,在Windows上, 我们可以使用UltraEdit等工具打开dmp文件,查看其导出字符集::


    我们知道在导出文件中,记录着导出使用的字符集id,通过查看导出文件头的第2、3个字节,我们可以找到16进制表示的字符集ID,在Windows上,
    我们可以使用UltraEdit等工具打开dmp文件,查看其导出字符集::

    在Unix上我们可以通过以下命令来查看:

    
    cat expdat.dmp | od -x | head
                          

    Oracle提供标准函数,对字符集名称及ID进行转换:

     

     
    SQL> select nls_charset_id('ZHS16GBK') from dual;
    
    NLS_CHARSET_ID('ZHS16GBK')
    --------------------------
                           852
    
    1 row selected.
    
    SQL> select nls_charset_name(852) from dual;
    
    NLS_CHAR
    --------
    ZHS16GBK
    
    1 row selected.
    
    十进制转换十六进制:
    
    SQL> select to_char('852','xxxx') from dual;
    
    TO_CH
    -----
      354
    
    1 row selected.
           

    对应上面的图中第2、3字节,我们知道该导出文件字符集为ZHS16GBk.

    查询数据库中有效的字符集可以使用以下脚本:

     

     
    col nls_charset_id for 9999
    col nls_charset_name for a30
    col hex_id for a20
    select 
    nls_charset_id(value) nls_charset_id,  
    value nls_charset_name,
    to_char(nls_charset_id(value),'xxxx') hex_id
    from  v$nls_valid_values
    where parameter = 'CHARACTERSET'
    order by nls_charset_id(value)
    /
          

    输出样例如下:

     

     
    NLS_CHARSET_ID NLS_CHARSET_NAME               HEX_ID
    -------------- ------------------------------ -------------
                 1 US7ASCII                           1
                 2 WE8DEC                             2
                 3 WE8HP                              3
                 4 US8PC437                           4
                 5 WE8EBCDIC37                        5
                 6 WE8EBCDIC500                       6
                 7 WE8EBCDIC1140                      7
                 8 WE8EBCDIC285                       8
     ...................
               850 ZHS16CGB231280                   352
               851 ZHS16MACCGB231280                353
               852 ZHS16GBK                         354
               853 ZHS16DBCS                        355
               860 ZHT32EUC                         35c
               861 ZHT32SOPS                        35d
               862 ZHT16DBT                         35e
               863 ZHT32TRIS                        35f
               864 ZHT16DBCS                        360
               865 ZHT16BIG5                        361
               866 ZHT16CCDC                        362
               867 ZHT16MSWIN950                    363
               868 ZHT16HKSCS                       364
               870 AL24UTFFSS                       366
               871 UTF8                             367
               872 UTFE                             368

    ..................................

     

    在很多时候,当我们进行导入操作的时候,已经离开了源数据库,这时如果目标数据库的字符集和导出文件不一致,很多时候就需要进行特殊处理,
    以下介绍几种方法,主要以US7ASCII和ZHS16GBK为例

    1. 源数据库字符集为US7ASCII,导出文件字符集为US7ASCII或ZHS16GBK,目标数据库字符集为ZHS16GBK
    在Oracle92中,我们发现对于这种情况,不论怎样处理,这个导出文件都无法正确导入到Oracle9i数据库中,这可能是因为Oracle9i的编码方案发生了较大改变。

    以下是我们所做的简单测试,其中导出文件命名规则为:


    S-Server ,后跟Server字符集
    C-client , 后跟导出操作时客户端字符集


    导入时客户端字符集设置在命令行完成,限于篇幅,我们省略了部分测试过程。
    对于Oracle9iR2,我们的测试结果是US7ASCII字符集,不管怎样转换,都无法正确导入ZHS16GBK字符集的数据库中。

    在进行导入操作时,如果字符不能正常转换,Oracle数据库会自动用一个”?”代替,也就是编码63。

     

     
    E:\nls2>set NLS_LANG=AMERICAN_AMERICA.US7ASCII
    
    E:\nls2>imp eygle/eygle file=Sus7ascii-Cus7ascii.dmp fromuser=eygle touser=eygle tables=test
    
    Import: Release 9.2.0.4.0 - Production on Mon Nov 3 17:14:39 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    Export file created by EXPORT:V09.02.00 via conventional path
    import done in US7ASCII character set and AL16UTF16 NCHAR character set
    import server uses ZHS16GBK character set (possible charset conversion)
    . . importing table                         "TEST"          2 rows imported
    Import terminated successfully without warnings.
    
    E:\nls2>sqlplus eygle/eygle
    
    SQL*Plus: Release 9.2.0.4.0 - Production on Mon Nov 3 17:14:50 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to:
    Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    SQL> select name,dump(name) from test;
    
    NAME DUMP(NAME)
    -----------------------------
    ???? Typ=1 Len=4: 63,63,63,63
    test Typ=1 Len=4: 116,101,115,116
    
    2 rows selected.
    
    SQL> exit
    Disconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    E:\nls2>set NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
    
    E:\nls2>imp eygle/eygle file=Sus7ascii-Cus7ascii.dmp fromuser=eygle touser=eygle tables=test ignore=y
    
    Import: Release 9.2.0.4.0 - Production on Mon Nov 3 17:15:28 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    Export file created by EXPORT:V09.02.00 via conventional path
    import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
    export client uses US7ASCII character set (possible charset conversion)
    . . importing table                         "TEST"          2 rows imported
    Import terminated successfully without warnings.
    
    E:\nls2>sqlplus eygle/eygle
    
    SQL*Plus: Release 9.2.0.4.0 - Production on Mon Nov 3 17:15:34 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to:
    Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    SQL> select name,dump(name) from test;
    
    NAME  DUMP(NAME)
    --------------------------------------------------------------------------------
    ????  Typ=1 Len=4: 63,63,63,63
    test  Typ=1 Len=4: 116,101,115,116
    ????  Typ=1 Len=4: 63,63,63,63
    test  Typ=1 Len=4: 116,101,115,116
    
    
    4 rows selected.
    
    SQL> drop table test;
    
    Table dropped.
    
    SQL> exit
    Disconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    E:\nls2>set NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
    
    E:\nls2>imp eygle/eygle file=Sus7ascii-Czhs16gbk.dmp fromuser=eygle touser=eygle tables=test ignore=y
    
    Import: Release 9.2.0.4.0 - Production on Mon Nov 3 17:17:21 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    Export file created by EXPORT:V09.02.00 via conventional path
    import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
    . . importing table                         "TEST"          2 rows imported
    Import terminated successfully without warnings.
    
    E:\nls2>sqlplus eygle/eygle
    
    SQL*Plus: Release 9.2.0.4.0 - Production on Mon Nov 3 17:17:30 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to:
    Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    SQL> select name,dump(name) from test;
    
    NAME DUMP(NAME)
    ----------------------------------------------
    ???? Typ=1 Len=4: 63,63,63,63
    test Typ=1 Len=4: 116,101,115,116
    
    2 rows selected.
    
    SQL> exit
    Disconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    E:\nls2>set NLS_LANG=AMERICAN_AMERICA.US7ASCII
    
    E:\nls2>imp eygle/eygle file=Sus7ascii-Czhs16gbk.dmp fromuser=eygle touser=eygle tables=test ignore=y
    
    Import: Release 9.2.0.4.0 - Production on Mon Nov 3 17:18:00 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    Export file created by EXPORT:V09.02.00 via conventional path
    import done in US7ASCII character set and AL16UTF16 NCHAR character set
    import server uses ZHS16GBK character set (possible charset conversion)
    export client uses ZHS16GBK character set (possible charset conversion)
    . . importing table                         "TEST"          2 rows imported
    Import terminated successfully without warnings.
    
    E:\nls2>sqlplus eygle/eygle
    
    SQL*Plus: Release 9.2.0.4.0 - Production on Mon Nov 3 17:18:08 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to:
    Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    SQL> select name,dump(name) from test;
    
    NAME DUMP(NAME)
    ----------------------------------------
    ???? Typ=1 Len=4: 63,63,63,63
    test Typ=1 Len=4: 116,101,115,116
    ???? Typ=1 Len=4: 63,63,63,63
    test Typ=1 Len=4: 116,101,115,116
    
    4 rows selected.
    
    SQL>
    
    

    对于这种情况,我们可以通过使用Oracle8i的导出工具,设置导出字符集为US7ASCII,导出后修改第二、三字符,修改 0001 为
    0354,这样就可以将US7ASCII字符集的数据正确导入到ZHS16GBK的数据库中。

    修改导出文件:

    导入修改后的导出文件:

     

     
    E:\nls2>set NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
    
    E:\nls2>imp eygle/eygle file=Sus7ascii-Cus7ascii-exp817.dmp fromuser=eygle touser=eygle tables=test
    
    Import: Release 9.2.0.4.0 - Production on Mon Nov 3 17:37:17 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    Export file created by EXPORT:V08.01.07 via conventional path
    import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
    export server uses UTF8 NCHAR character set (possible ncharset conversion)
    . . importing table                         "TEST"          2 rows imported
    Import terminated successfully without warnings.
    
    E:\nls2>sqlplus eygle/eygle
    
    SQL*Plus: Release 9.2.0.4.0 - Production on Mon Nov 3 17:37:23 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to:
    Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    SQL> select name,dump(name) from test;
    
    NAME     DUMP(NAME)
    --------------------------------------------------------------------------------
    测试       Typ=1 Len=4: 178,226,202,212
    Test        Typ=1 Len=4: 116,101,115,116
    
    2 rows selected.
    
    SQL>
    

    2. 使用create database的方法
    如果导出文件使用的字符集是US7ASCII,目标数据库的字符集是ZHS16GBK,我们可以使用create database的方法来修改,具体如下:

     

     
    SQL> col parameter for a30
    SQL> col value for a30
    SQL> select * from v$nls_parameters;
    
    PARAMETER                      VALUE
    ------------------------------ ------------------------------
    NLS_LANGUAGE                   AMERICAN
    NLS_TERRITORY                  AMERICA
    NLS_CURRENCY                   $
    NLS_ISO_CURRENCY               AMERICA
    NLS_NUMERIC_CHARACTERS         .,
    NLS_CALENDAR                   GREGORIAN
    NLS_DATE_FORMAT                DD-MON-RR
    NLS_DATE_LANGUAGE              AMERICAN
    NLS_CHARACTERSET               ZHS16GBK
    NLS_SORT                       BINARY
    ……………….
    
    19 rows selected.
    
    SQL> create database character set us7ascii;
    create database character set us7ascii
    *
    ERROR at line 1:
    ORA-01031: insufficient privileges
    
    
    SQL> select * from v$nls_parameters;
    
    PARAMETER                      VALUE
    ------------------------------ ------------------------------
    NLS_LANGUAGE                   AMERICAN
    NLS_TERRITORY                  AMERICA
    NLS_CURRENCY                   $
    NLS_ISO_CURRENCY               AMERICA
    NLS_NUMERIC_CHARACTERS         .,
    NLS_CALENDAR                   GREGORIAN
    NLS_DATE_FORMAT                DD-MON-RR
    NLS_DATE_LANGUAGE              AMERICAN
    NLS_CHARACTERSET               US7ASCII
    NLS_SORT                       BINARY
    …………..
    
    19 rows selected.
    
    SQL> exit
    Disconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    E:\nls2>set nls_lang=AMERICAN_AMERICA.US7ASCII
    
    E:\nls2>imp eygle/eygle file=Sus7ascii-Cus7ascii.dmp fromuser=eygle touser=eygle
    
    Import: Release 9.2.0.4.0 - Production on Sun Nov 2 14:53:26 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    Export file created by EXPORT:V09.02.00 via conventional path
    import done in US7ASCII character set and AL16UTF16 NCHAR character set
    import server uses ZHS16GBK character set (possible charset conversion)
    . . importing table                         "TEST"          2 rows imported
    Import terminated successfully without warnings.
    
    E:\nls2>sqlplus eygle/eygle
    
    SQL*Plus: Release 9.2.0.4.0 - Production on Sun Nov 2 14:53:35 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to:
    Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    SQL> select * from test;
    
    NAME
    ----------
    测试
    test
    
    2 rows selected.
    
    

    我们看到,当发出create database character set us7ascii;命令时,数据库v$nls_parameters中的字符集设置随之更改,该参数影响导入进程,
    更改后可以正确导入数据,重起数据库后,该设置恢复。

    提示:v$nls_paraemters来源于x$nls_parameters,该动态性能视图影响导入操作;而nls_database_parameters来源于props$数据表,影响数据存储。

    3. Oracle提供的字符扫描工具csscan

    我们说以上的方法只是应该在不得已的情况下使用,其本质是欺骗数据库,强制导入数据,可能损失元数据。
    如果要确保数据的完整性,应该使用csscan扫描数据库,找出所有不兼容的字符,然后通过编写相应的脚本及代码,在转换之后进行更新,确保数据的正确性。
    我们简单看一下csscan的使用。

    要使用csscan之前,需要以sys用户身份创建相应数据字典对象:

     

     
    E:\nls2>sqlplus "/ as sysdba"
    
    SQL*Plus: Release 9.2.0.4.0 - Production on Sun Nov 2 19:42:07 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Connected to:
    Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    SQL> select instance_name from v$intance;
    select instance_name from v$intance
                              *
    ERROR at line 1:
    ORA-00942: table or view does not exist
    
    
    SQL> select instance_name from v$instance;
    
    INSTANCE_NAME
    ----------------
    penny
    
    1 row selected.
    
    SQL> @?/rdbms/admin/csminst.sql
    
    User created.
    
    
    Grant succeeded.
    
    ………..
    
                    

    这个脚本创建相应用户(csmig)及数据字典对象,扫描信息会记录在相应的数据字典表里。

    我们可以在命令行调用这个工具对数据库进行扫描:

     
    E:\nls2>csscan FULL=Y FROMCHAR=ZHS16GBK TOCHAR=US7ASCII LOG=US7check.log CAPTURE=Y ARRAY=1000000 PROCESS=2
    
    
    Character Set Scanner v1.1 : Release 9.2.0.1.0 - Production on Sun Nov 2 20:24:45 2003
    
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
    
    
    Username: eygle/eygle
    
    Connected to:
    Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.4.0 - Production
    
    Enumerating tables to scan...
    
    . process 1 scanning SYS.SOURCE$[AAAABHAABAAAAIRAAA]
    . process 2 scanning SYS.ATTRIBUTE$[AAAAEoAABAAAAhZAAA]
    . process 2 scanning SYS.PARAMETER$[AAAAEoAABAAAAhZAAA]
    . process 2 scanning SYS.METHOD$[AAAAEoAABAAAAhZAAA]
    ……..
    . process 2 scanning SYSTEM.DEF$_AQERROR[AAAA8fAABAAACWJAAA]
    . process 1 scanning WMSYS.WM$ENV_VARS[AAABeWAABAAAFMZAAA]
    ………………….
    . process 2 scanning SYS.UGROUP$[AAAAA5AABAAAAGpAAA]
    . process 2 scanning SYS.CON$[AAAAAcAABAAAACpAAA]
    . process 1 scanning SYS.FILE$[AAAAARAABAAAABxAAA]
    
    Creating Database Scan Summary Report...
    
    Creating Individual Exception Report...
    
    Scanner terminated successfully.
          

    然后我们可以检查输出的日志来查看数据库扫描情况:

     
    Database Scan Individual Exception Report
    
    
    [Database Scan Parameters]
    
    Parameter                      Value                                           
    ------------------------------ ------------------------------------------------
    Scan type                      Full database                                   
    Scan CHAR data?                YES                                             
    Current database character set ZHS16GBK                                        
    New database character set     US7ASCII                                        
    Scan NCHAR data?               NO                                              
    Array fetch buffer size        1000000                                         
    Number of processes            2                                               
    Capture convertible data?      YES                                             
    ------------------------------ ------------------------------------------------
    
    [Data Dictionary individual exceptions]
    
    
    [Application data individual exceptions]
    
    User  : EYGLE
    Table : TEST
    Column: NAME
    Type  : VARCHAR2(10)
    Number of Exceptions         : 1         
    Max Post Conversion Data Size: 4         
    
    ROWID              Exception Type      Size Cell Data(first 30 bytes)     
    ------------------ ------------------ ----- ------------------------------
    AAABpIAADAAAAAMAAA lossy conversion         测试                          
    ------------------ ------------------ ----- ------------------------------
    

     

    不能转换的数据将会被记录下来,我们可以根据这些信息在转换之后,对数据进行相应的更新,确保转换无误

    展开全文
  • 一、什么是Oracle字符集Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序...
  • ORACLE 查看数据库字符集

    千次阅读 2020-03-02 09:54:28
    涉及三方面的字符集, 1. oracel server端的字符集; 2. oracle client端的字符集; 3. dmp文件的字符集。...有很种方法可以查出oracle server端的字符集,比较直观的查询方法是以下这种: SQL> select u...
  • ORACLE数据库有国家字符集(national character set)与数据库字符集(database character set)之分。两者都是在创建数据库时需要设置的。国家字符集主要是用于NCHAR、NVARCHAR、NCLOB类型的字段数据,而数据库字符集...
  • ORACLE如何修改字符集

    千次阅读 2019-01-22 09:46:04
    数据导入时报ORA-12899错误,即插入的数据长度超出字段的设置长度,实际长度并不长,这是由于Oracle字符集不同,汉字占的长度不同造成的。中文在ZHS16GBK中占2个字节,在UTF-8中却占3个字节,所以汉字导入UTF-8字符...
  • oracle 字符集

    2017-12-29 11:23:38
     Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币...
  • Oracle字符集的查看查询和Oracle字符集的设置修改
  • 服务器端:(oracle服务器端字符集) 数据库字符集在创建数据库时指定,在创建后通常不能更改。在创建数据库时,可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。 1. 字符集:  (1)用来存储...
  • Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币,...
  • Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。一般来说,数据库字符集在安装数据库实例时就指定好了,而且...
  • 2. oracle client端的字符集; 3. dmp文件的字符集。在做数据导入的时候,需要这三个字符集都一致才能正确导入。 于是查找一些资料,如何来修改数据库和客户端的字符集,以及如何来查看对应的dmp文件的字
  • Oracle 一个中文汉字 占用几个字节,要根据Oracle字符集编码决定 查看oracle server端字符集 select userenv('language') from dual; 如果显示如下,一个汉字占用两个字节 SIMPLIFIED CHINESE_CHINA.ZHS16GBK 如果...
  • ORACLE数据库字符集

    万次阅读 2019-08-09 17:47:49
    ORACLE数据库字符集 一.字符集基本知识 二、查询oracle server端的字符集 三.修改oracle字符集 字符集基本知识 1.基本认知 ORACLE数据库字符集,即Oracle...由于oracle字符集种类,且在存储、检索、迁移o...
  • oracle学习笔记 字符集正确设置及相关操作 这节课讲的是字符集针对DBA来讲该如何去关注的问题 以后在weblogic在备份恢复里面还要继续关注字符集的概念 一)oracle环境 DBA来讲我们常见的环境是 用windows做...
  • Oracle字符集

    2013-09-04 00:15:06
     Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币...
  • Oracle学习之Oracle字符集

    千次阅读 2016-09-07 08:32:29
    Oracle字符集是一个字节数据的解释的符号的集合,有大小之分,有相互的包容关系。Oracle支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据块工具,错误消息,排序次序,日期,时间,货币...
  • oracle10g字符集的查看与修改

    千次阅读 2013-08-15 17:28:17
     Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币...
  •  Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币...
  • Oracle语言和字符集设置

    千次阅读 2013-07-26 14:02:57
     Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币...
  • 选择ORACLE数据库字符集 转自:https://www.cnblogs.com/buxingzhelyd/p/8670161.html 如何选择数据库的字符集是一个有争议的话题,字符集本身涉及的范围很广,它与应用程序、客户的本地环境、操作系统、服务器等关系...
  • 复制Oracle数据库中文字符集AMERICAN_AMERICA.ZHS16GBK数据到目的库Oracle字符集AL32UTF8

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 40,929
精华内容 16,371
关键字:

oracle多字节字符集错误