精华内容
下载资源
问答
  • 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字符集的设置修改

    我们知道在导出文件中,记录着导出使用的字符集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截取字符(substr)检索字符位置(instr)的使用,需要的朋友可以参考下
  • 本文主要讨论以下几个部分:如何查看查询oracle字符集、 修改设置字符集以及常见的oracle utf8字符集和oracle exp 字符集问题。 一、什么是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 utf8字符集和oracle exp 字符集问题。 一、什么是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文件的字符集

    oracleexp工具导出的dmp文件也包含了字符集信息,dmp文件的第2和第3个字节记录了dmp文件的字符集。如果dmp文件不大,比如只有几M或几十M,可以用UltraEdit打开(16进制方式),看第23个字节的内容,如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平台下,就是注册表里面相应OracleHomeNLS_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,表示会话自己的设置,可能是会话的环境变量或者是altersession完成,如果会话没有特殊的设置,将与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端的字符集。特别说明,我们最常用的两种字符集ZHS16GBKZHS16CGB231280之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持。

     

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

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

    2. 通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8US7ASCII的超集,修改数据库字符集可使用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_USEAL32UTF8;

    SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USEAL16UTF16;

     

    SQL>SHUTDOWN IMMEDIATE;

    SQL>STARTUP

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

     

    若出现‘ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when NCLOBdata 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_USEUTF8;

    SQL>SHUTDOWN immediate;

    SQL>startup;

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

     

    3.2 修改dmp文件字符集

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

     

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

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

    0354

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

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

     

    3.3客户端字符集设置方法

         1)UNIX环境

            $NLS_LANG=simplifiedchinese_china.zhs16gbk

             $exportNLS_LANG

             编辑oracle用户的profile文件

        2)Windows环境

             编辑注册表

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

      或者在窗口设置:

            setnls_lang=AMERICAN_AMERICA.ZHS16GBK

    四.字符集的相关知识:

    4.1 字符集

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

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

        <Language><bitsize><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-16unicode16位编码方式,是一种定长多字节编码,用2个字节表示一个unicode字符,AF16UTF16UTF-16编码字符集。

        UTF-8unicode8位编码方式,是一种变长多字节编码,这种编码可以用123个字节表示一个unicode字符,AL32UTF8UTF8UTFEUTF-8编码字符集

     

    4.3 字符集超级

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

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

     

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

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

     

    4.4.1字符集

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

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

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

     

    4.4.2国家字符集:

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

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

     

    4.4.3查询字符集参数

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

        nls_database_parametersprops$v$nls_parameters

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

     

    4.4.4修改数据库字符集

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

     

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

    2. 通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8US7ASCII的超集,修改数据库字符集可使用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 characterset>

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

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

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

        例如:NLS_LANG=AMERICAN_AMERICA.US7ASCII

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

     

    4.5.3客户端字符集设置方法

         1)UNIX环境

            $NLS_LANG=simplifiedchinese_china.zhs16gbk

             $exportNLS_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)源数据库字符集

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

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

       4)目标数据库字符集

     

    5.2导出的转换过程

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

     

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

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

     

    5.3导入的转换过程

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

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

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

        3IMP读取导出文件

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

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

     

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

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


    转自 http://blog.csdn.net/kevin_lcc/article/details/44912453

    展开全文
  • 查找字符位置语句:instr select instr(t.f_fylxmc,'-')from w_w_fm_day_cost t 返回结果是0,索引从0开始 截取字符串位置语句:substr select substr(t.f_fylxmc, instr(t.f_fylxmc,'-')+1,100) from w_w_fm_...
  • 简介:ORACLE数据库字符集,即Oracle全球化支持(Globalization Support),或即国家语言支持(NLS)其作用是用本国语言和格式来存储、处理和检索数据。利用全球化支持,ORACLE为用户提供自己熟悉的数据库母语环境,...
  • Oracle字符串截取最全方法总结

    万次阅读 多人点赞 2018-08-30 18:10:42
    substr 函数:截取字符串 ...start:开始位置,从1开始查找。如果start是负数,则从string字符串末尾开始算起。 length:可选项,表示截取字符串长度。 示例: SELECT SUBSTR('Hello SQL!', 1) FROM dual ...
  • Oracle 获取字符位置并截取字符

    千次阅读 2020-10-28 10:14:58
    1、获取字符所在位置 用法:instr (字符串, 查找的字符) select instr('福建省/厦门市/思明区', '/') from dual; 返回值:4 2、截取字符串 用法:substr(字符串, 开始位置, 截取长度) select substr('福建省/厦门...
  • Oracle字符

    千次阅读 2013-12-22 22:13:02
    一、什么是Oracle字符集  Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,...
  • ORACLE字符函数

    千次阅读 2019-04-08 10:36:27
    ORACLE字符函数 开发工具与关键技术:Oracle sql*plus PLSQL Developer 作者:邓高发 撰写时间:2019年4月6日 SQL中有许多函数,其中分为两大类: 1.单行函数:从字面上理解就是,对单行数据进行操作的的函数。 2.多行...
  • oracle字符串拼接

    万次阅读 2019-05-06 02:28:14
    一、“||”拼接 类似于“+”号 二、CONCAT()函数 除了“||”,Oracle还支持使用CONCAT()函数进行字符串拼接,但是只支持两个字符: 三、多个CONCAT()函数嵌套 如果需要拼接多个字符串,可以进行嵌套: ...
  • oracle字符集的查看,oracle客户端字符集的修改
  • Oracle 字符集的查看和修改 Oracle 字符集的查看和修改
  • 本文主要讨论以下几个部分:如何查看查询oracle字符集、 修改设置字符集以及常见的oracle utf8字符集和oracle exp 字符集问题。 一、什么是Oracle字符集  Oracle字符集是一个字节数据的解释的符号集合,有大小之分...
  • 数据库的全球化特性是数据库发展的必然结果...Oracle数据库统一字符集为AL32UTF8,可以参考:Oracle 全球化特性与字符集。对于不同的字符集容易出现转换乱码,同时不同字符集也影响存储空间的占用。 如本文下面的描述。
  • oracle 字符

    千次阅读 2009-12-22 09:24:00
    一.引言  ORACLE数据库字符集,即Oracle全球化支持(Globalization Support),或即国家语言支持(NLS)其作用是用本国...Oracle可以支持多种语言及字符集,其中oracle8i支持48种语言、76个国家地域、229种字符集,而
  • Oracle删除字符串中指定位置字符

    千次阅读 2019-06-26 17:14:55
    实现其实很简单,就是是利用substr()先截取要删除位置前面的,再和后面的拼接就可以了 sql:select bill_type from itf_bpm_data select substr(bill_type,0,3)||substr(bill_type,5) from itf_bpm_data 换成...
  • Oracle字符串拼接

    千次阅读 2019-01-03 19:37:02
    Oracle中使用“||”进行字符串连接,使用方式如下 SELECT "我的成绩为" || score FROM TABLE1 T1 WHERE T1.NAME="souter" 还可以使用CONCAT()方法进行字符串拼接,注意,CONCAT()方法只支持...
  • oracle 常用命令(查看oracle字符集)

    千次阅读 2017-06-07 10:15:52
    select userenv('language'... 查看oracle字符集   alter user scott account unlock; 解锁   select username,lock_date from dba_users where username='scott'; 查看锁定时间   select b.owner,b.object_
  • Oracle字符转义

    千次阅读 2012-08-02 18:31:56
    以下的文章主要介绍的是Oracle insert插入转义字符 ,单引号'与&符的相关问题,如果你觉得它们的名字很怪异,而且在实际的应用中也很少的涉及到它们的具体应用的话,以下的文章就是相关问题的解答。 今天在导入一...
  • oracle字符集更改

    千次阅读 2019-05-20 14:33:34
    问题由来,解决[Err] ORA-12899: 列 "XXXXX"."XXXXXXX"."XXXXX" 的值太大 (实际值: 48, ...原因:数据库的字符集不同导致的, 解决:修改本地数据库的字符集更改为ZHS16GBK 1,查看数据库的字符集 select * from v...
  • oracle字符串处理函数汇总

    千次阅读 2018-08-11 10:59:22
    字符函数的返回类型所受的限制和基本数据库类型所受的限制是相同的,比如: VARCHAR2数值被限制为2000字符(ORACLE 8中为4000字符),而CHAR数值被限制为255字符(在ORACLE8中是2000).当在过程性语句中使用时,...
  • oracle 字符串转数字

    万次阅读 2019-07-11 16:52:34
    字符串转成数字 CREATE OR REPLACE FUNCTION char_to_number( C VARCHAR2) RETURN FLOAT IS N number; BEGIN BEGIN N :=to_number(C); RETURN N; EXCEPTION WHEN OTHERS THEN RETURN null; END; E...
  • Oracle字符串拼接的方法

    千次阅读 2018-08-11 14:13:39
    和其他数据库系统类似,Oracle字符串连接使用“||”进行字符串拼接,其使用方式和MSSQLServer中的加号“+”一样。 比如执行下面的SQL语句: 复制代码代码如下:   SELECT '工号为'||FNumber||'的员工姓名为'||...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 304,675
精华内容 121,870
关键字:

oracle字符位置