精华内容
下载资源
问答
  • oracle不同字符集导入导出(GBK导入UTF8) 转自: https://www.cnblogs.com/huangen88/p/4664759.html 因数据库迁移,需要将原oracle备份文件导入新的oracle数据库中,EXP导出后,IMP报错,发现字符串长度太长...

    oracle不同字符集导入导出(GBK导入UTF8)

    转自: https://www.cnblogs.com/huangen88/p/4664759.html

     

    因数据库迁移,需要将原oracle备份文件导入新的oracle数据库中,EXP导出后,IMP报错,发现字符串长度太长报错。查找后发现,原数据库为GBK字符集(oracle在varchar2类型中一个汉字占用两位),新数据库为UTF8字符集(一个汉子占用三位)。

    解决方法如下,将原数据库所有含varchar2的字段的长度批量修改。

    修改分为两步,varchar2最长支持4000的长度,若carchar2长度存在超过2667(4000*2/3)的,可修改为CLOB类型,或者验证字段中最长的使用长度,若低于2667,调整为4000即可。

    批量修改方法如下:

    create or replace procedure p_test as

    CURSOR TEMP IS
    SELECT TABLE_NAME, COLUMN_NAME, ceil(DATA_LENGTH*3/2) DATA_LENGTH
    FROM USER_TAB_COLUMNS
    WHERE DATA_TYPE = 'VARCHAR2'
    and DATA_LENGTH < 2000;
    STR VARCHAR2(100) := '';
    BEGIN
    FOR S IN TEMP LOOP
    STR := 'ALTER TABLE ' || S.TABLE_NAME || ' MODIFY(' || S.COLUMN_NAME ||
    ' VARCHAR2(' || DATA_LENGTH || '))';
    DBMS_OUTPUT.PUT_LINE(STR);
    EXECUTE IMMEDIATE STR;

    END LOOP;
    END;

    注意:若存在字段的函数索引,批量修改会报错需将函数索引删除,才可执行。

    最后,导出dmp,然后IMP导入即可。

     

     

    转载于:https://www.cnblogs.com/fengaix6/p/8562840.html

    展开全文
  • oracle导出文件字符集修改 博客分类:  oracle 9i/10g OracleSQLSQL ServerSecurityC#  我们知道在导出文件中,记录着导出使用的字符集id,通过查看导出文件头的第2、3个字节,我们可以找到16进制...


    我们知道在导出文件中,记录着导出使用的字符集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         测试                          
    ------------------ ------------------ ----- ------------------------------
    

     

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

    展开全文
  • 开篇:因为要定位一个 关于dmp文件导入的乱码问题, 于是乎我开始了漫长了 Oracle字符集搜索之路,网上关于讲解oracle字符集的文章多得数不胜数,但转载的这篇文章确是我最最喜欢的,图文并茂,恰当的例子通俗易懂,...

    开篇:因为要定位一个 关于dmp文件导入的乱码问题, 于是乎我开始了漫长了 Oracle字符集搜索之路,网上关于讲解oracle字符集的文章多得数不胜数,但转载的这篇文章确是我最最喜欢的,图文并茂,恰当的例子通俗易懂,对于我这种小菜最最适合不过。

    本文转自:http://blog.163.com/jiankun_liu/blog/static/1863927762013698175289/

    原文标题:Oracle_字符集问题(数据库与客户端字符集关联关系)

    //时间:2013-07-07

    //作者:shm

    //描述:本文主要记录了Oracle数据库的字符集问题,也涉及作为服务器操作系统的CentOS或者Windows的字符集与Oracle字符集之间的关联关系。

    Oracle的字符集,这个问题的提出是因为两个原因:一是工作中遇到一个DMP文件需要恢复到数据库中去,而这个DMP文件的字符集是US7ASCII,第二个原因是一直在学习CentOS,在这个系统上安装Oracle已经能成功,但是被中文英文系统字符集等问题搞得有点头大。所以又回头翻了翻盖国强的书、看了看尚观的视频,终于有点心得,所以就写下了这篇算是笔记的文章。

    Oracle数据库的字符集问题不算是大问题,但也是一个头疼的问题。这是因为有这么三个原因:一是Oracle数据库在安装时指定好字符集之后一般不能更改,二是字符集问题涉及服务器与客户端之间的存取问题,三是Oracle数据库迁移时也会跟字符集非常相关。

    首先,要说清楚Oracle字符集的相关问题,则要先理清数据库运行过程中的架构以及在这个架构中的字符集设置及这些设置之间的关联关系。

    先画一张图看一下:

    在这个图中,为了说明问题,我们将服务器与客户端分开,客户端用应用程序比如sqlplus或者PL/SQL与服务端相连。

    服务端有两个字符集:服务端操作系统字符集(4)、服务端数据库字符集(1);

    客户端有一个字符集:客户端操作系统字符集(2);

    客户端有一个参数:操作系统参数NLS_LANG(3)。

    这三个字符集与一个参数中,有一个字符集对整个架构的运行没有影响,它就是服务端操作系统字符集(4),所以这个字符集将不再出现在我们的讨论过程中。

    为什么这个服务端操作系统字符集没有用呢?这是因为Oracle在存取字符时与客户端进行字符集确认与转码的过程是由Oracle数据库自身完成的,不需要经过Oracle数据库所在的服务器的帮助。具体的是怎么回事用以下例子说明一下。

    比如在Oracle数据库中有一个表,用如下语句创建:

    create table test(name varchar2(10));

    为了说明问题假定有这样的一个环境:服务器端Oracle数据库的字符集是UTF8,客户端操作系统字符集是ZHS16GBK,客户端NLS_LANG参数设置为ZHS16GBK。

    那么从客户端应用程序(比如sqlplus)发出这样一条命令:

    insert into test (name) values('中国');

    首先,这里有一个字符串“中国”,客户端操作系统用ZHS16GBK对它进行编码,比如编成“167219”,并把它交给sqlplus程序,然后把它发送给Oracle数据库。

    接着,Oracle数据库收到一串编码“167219”,不是直接往数据库里一扔就完事的,它要问客户端操作系统:“请问你给我的这串代码是用什么格式编码的啊?”客户端操作系统怎么回答?它会这么回答:“编码格式请参照参数NLS_LANG”。Oracle数据库一看,NLS_LANG='ZHS16GBK',这个编码格式与Oracle数据库自身的编码格式“UTF8”不一样,然后就是Oracle数据库发挥自己专长的地方了,为什么呢?因为Oracle数据库有它自己的编码表,而且不是一张而是好多张编码表,它可以根据编码表对编码进行翻译和转码。这就好比Oracle数据库是一个翻译,它会好几国语言,牛人一个。像上面的这个情况,Oracle会把“167219”这串代码拿过来,根据参数NLS_LANG查ZHS16GBK编码表,找到对应这串代码的字符“中国”,然后再到UTF8编码表中查“中国”对应的编码,比如查到的结果是“3224678”。

    最后,将转码之后的编码“3224678”存放到Oracle数据库中去。

    为了进一步说明问题,我们再执行一条语句:

    select name from test;

    首先,Oracle数据库会从数据库中取出一串代码“3224678”。

    接着,Oracle数据库不是直接把这串代码交给sqlplus程序,它会多问一句:“代码串我是取出来了,它是UTF8编码格式的,请问sqlplus,你希望要什么编码格式的?”,sqlplus仍然会很爽快地告诉Oracle数据库:“编码格式请继续参照参数NLS_LANG”。Oracle数据库一看,ZHS16GBK跟UTF8又不一样,所以先查UTF8编码表,找到编码“3224678”对应的字符“中国”,再查ZHS16GBK编码表,找到“中国”对应的编码“167219”,然后就是把最后得到的这串编码“167219”交给sqlplus程序。

    最后,sqlplus直接把得到的这串编码扔给客户端操作系统,而操作系统只有ZHS16GBK编码表,它不会问得到的这串编码是什么格式的,只会直接到ZHS16GBK编码表中去查“167219”对应的字符是什么,并把它交给应用程序显示出来。这个显示的结果是“中国”。

    以上就是一个完整的从客户端编码并经过Oracle数据库转码存入数据库,然后从数据库取出并转码交给客户端显示的实验。

    从以上过程我们可以得出以下一些结论:

    1.对Oracle数据库存取起作用的是这些:客户端操作系统字符集、客户端操作系统参数NLS_LANG、服务端数据库字符集。

    2.对Oracle数据库不起作用的是服务端操作系统字符集。

    3.客户端操作系统只有一张编码表,与客户端字符集对应。

    4.Oracle数据库的字符集只有一个,并且固定,一般不改变。

    5.存放在Oracle数据库中的字符串的编码格式只有一个,它就是数据库的字符集所对应的编码格式。

    6.Oracle数据库有很多张编码表,可以在数据存入时将其它编码格式的编码转换为数据库字符集指定的格式,取出时从数据库字符集指定的格式转换为其它编码格式。

    7.整个架构中的转码只发生在Oracle数据库边界上,其它地方没有。

    8.Oracle是根据客户端操作系统的参数NLS_LANG与自己的字符集进行对照来确定是否需要进行转码的。

    最最重要的结论出来了:

    9.Oracle数据库如何选择字符集?只有一个原则,那就是这个字符集要包含数据库运行过程中所能存入的数据字符,通常作为中国人我们选择ZHS16GBK,如果想再保险一点,选择AL32UTF8。

    10.服务器操作系统选择什么字符集?这个字符集与数据库字符集一点关系都没有,只跟谁有关?操作系统管理员!所以它的选择原则是,系统管理员想选择什么就选择什么。

    11.客户端操作系统选择什么字符集?我是中国人,我用中文操作系统,所以我选择ZHS16GBK。建议中国人都选择ZHS16GBK。

    12.客户端操作系统参数NLS_LANG参数如何设置?这个只有一个设置方法,那就是与操作系统字符集相同。要不然会出问题的……

    最最最最重要的一句话:

    最好的,最不容易出字符集错误的就是:将数据库字符集、客户端字符集、客户端操作系统NLS_LANG参数三个地方作同样的设置。

    另外再记录一下EXP和IMP过程与字符集相关的事情。

    EXP时,起作用的有Oracle数据库的字符集和客户端操作系统参数NLS_LANG两项,这时服务器与客户端操作系统字符集都不起作用。如果客户端操作系统参数NLS_LANG与Oracle数据库的字符集相同,那就直接导出,不需要转码,并且导出文件的字符集与上述两项一样;如果客户端操作系统参数NLS_LANG与Oracle数据库的字符集不同,那么导出时Oracle数据库会将数据文件从Oracle数据库的字符集编码格式转码成客户端操作系统参数NLS_LANG指定的编码格式。总而言之一句话:导出文件的字符集格式与导出客户端操作系统参数NLS_LANG一定相同。

    IMP时,起作用的仍然是两项,一项是DMP文件第二第三字节指定的字符集,另外一项是Oracle数据库的字符集。两个相同就不需要转码,两个不同就转成Oracle数据库字符集指定的编码格式。

    最后记录我遇到的几个问题。

    1.我前段时间测试过在CentOS上安装Oracle11gR2,那时我设置过CentOS的字符集中“zh_CN.UTF-8”,并且安装中文字体,当时也确实能得到我想要的结果,那就是:我安装的Oracle数据库的字符集是中文字符集ZHS16GBK。为什么呢,因为Oracle数据库的字符集是默认地根据操作系统的字符集来的,并且我也就选择它的默认字符集。所以没有出错。

    但是,但是,现在我知道了,这个作为服务器的CentOS的字符集对Oracle数据库没有影响,所以现在让我再来一回去选择它是什么字符集,我会选择en_US.UTF-8,甚至en_US.US7ASCII。为什么呢,因为在shell界面显示中文确认是一个难题,所以管理CentOS,还是用英文吧,比较方便又对数据库没影响。随它去吧。

    2.英文操作系统安装中文字符集oracle数据库时,一定要注意在选择数据库字符集的时候慢一点,细心地选择一个ZHS16GBK或者AL32UTF8。

    3.DMP文件是US7ASCII字符集,要把它导入字符集是ZHS16GBK的数据库中去,如何操作?第一步:安装一个US7ASCII字符集的数据库(比如说9i);第二步,将DMP文件导入该数据库;第三步,设置导出客户端操作系统参数NLS_LANG=ZHS16GBK,然后导出;第四步,将后导出的DMP文件导入字符集是ZHS16GBK的数据库中去。理论上成功。需要做实验测试。

    4.曾经说到,一般情况下数据库的字符集在数据库安装好之后就不可以更改。那么如果万一领导说一定要改,怎么办?比如说原来的字符集是ZHS16GBK,非要让转成UTF8,有没有办法?答案是有的,但是,但是不一定会全部成功,这里有一个严格超集的概念,这个概念在这篇文章里不讲。答案是这么做,设置导出客户端操作系统参数为UTF8,然后导出,这里,数据编码格式会从ZHS16GBK转码成UTF8,然后再删除ZHS16GBK的数据库,新建一个UTF8的数据库,再导入就可以了。

    展开全文
  • 查找后发现,原数据库为GBK字符集oracle在varchar2类型中一个汉字占用两位),新数据库为UTF8字符集(一个汉子占用三位)。 解决方法如下,将原数据库所有含varchar2的字段的长度批量修改。 修改分为两步,...

    因数据库迁移,需要将原oracle备份文件导入新的oracle数据库中,EXP导出后,IMP报错,发现字符串长度太长报错。查找后发现,原数据库为GBK字符集(oracle在varchar2类型中一个汉字占用两位),新数据库为UTF8字符集(一个汉子占用三位)。

    解决方法如下,将原数据库所有含varchar2的字段的长度批量修改。

    修改分为两步,varchar2最长支持4000的长度,若carchar2长度存在超过2667(4000*2/3)的,可修改为CLOB类型,或者验证字段中最长的使用长度,若低于2667,调整为4000即可。

    批量修改方法如下:

    create or replace procedure p_test as

    CURSOR TEMP IS
    SELECT TABLE_NAME, COLUMN_NAME, ceil(DATA_LENGTH*3/2) DATA_LENGTH
    FROM USER_TAB_COLUMNS
    WHERE DATA_TYPE = 'VARCHAR2'
    and DATA_LENGTH < 2000;
    STR VARCHAR2(100) := '';
    BEGIN
    FOR S IN TEMP LOOP
    STR := 'ALTER TABLE ' || S.TABLE_NAME || ' MODIFY(' || S.COLUMN_NAME ||
    ' VARCHAR2(' || DATA_LENGTH || '))';
    DBMS_OUTPUT.PUT_LINE(STR);
    EXECUTE IMMEDIATE STR;

    END LOOP;
    END;

    注意:若存在字段的函数索引,批量修改会报错需将函数索引删除,才可执行。

    最后,导出dmp,然后IMP导入即可。

     

    转载于:https://www.cnblogs.com/huangen88/p/4664759.html

    展开全文
  • ORACLE数据库字符集

    万次阅读 2019-08-09 17:47:49
    ORACLE数据库字符集 一.字符集基本知识 二、查询oracle server端的字符集 三.... 字符集基本知识 1.基本认知 ORACLE数据库字符集,即Oracle全球化支持...由于oracle字符集种类多,且在存储、检索、迁移o...
  • 服务器端:(oracle服务器端字符集) 数据库字符集在创建数据库时指定,在创建后通常不能更改。在创建数据库时,可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。 1. 字符集:  (1)用来存储...
  • 本文主要讨论以下几个部分:如何查看查询oracle字符集、 修改设置字符集以及常见的oracle utf8字符集和oracle exp 字符集问题。 一、什么是Oracle字符集  Oracle字符集是一个字节数据的解释的符号集合,有大小之分...
  • Oracle如何使用spool导出utf8字符集的文本文件 --cmd里的字符集 chcp 65001 就是换成UTF-8代码页 ...
  • Oracle字符集的查看查询和Oracle字符集的设置修改
  • oracle修改字符集

    2017-03-09 18:33:42
    生产环境的数据表用了 中文字段名。...生产oracle字符集是:NLS_CHARACTERSET ZHS16GBK 开发oracle字符集是:NLS_CHARACTERSET AL16UTF16 开发oracle需要修改字符集和生产一致。 开发下: select * from V$nls_Par
  • Oracle字符集的查看查询和Oracle字符集的设置修改
  • 一:实际数据库是使用v$nls_parameters中的设置: select * from v$nls_parameters t where t.PARAMETER ='NLS_LANGUAGE' or t.PARAMETER ='NLS_CHARACTERSET'; 等于: select userenv('...数据库字符集nls_datab
  • oracle 修改字符集 修改为ZHS16GBK

    万次阅读 多人点赞 2018-08-24 16:18:56
    可以用下面的方法将数据库的字符集修改一下(改成跟你导出时的字符一样)。 注:设置环境变量是用来处理PL/SQL字符问题的,不要吴会是已经将数据库的字符集修改了。 1.cmd 2.输入set ORACLE_SID=你想进入的...
  • 一.引言  ORACLE数据库字符集,即Oracle全球化支持(Globalization Support),或即国家语言支持(NLS)其作用是用本国...Oracle可以支持多种语言及字符集,其中oracle8i支持48种语言、76个国家地域、229种字符集,而
  • 一.引言  ORACLE数据库字符集,即Oracle全球化支持(Globalization Support),或即国家语言支持(NLS)其作用是用本国...Oracle可以支持多种语言及字符集,其中oracle8i支持48种语言、76个国家地域、229种字符集,而
  • Oracle 数据库字符集总结

    千次阅读 2011-07-07 22:35:19
    Oracle中常用的字符集包括US7ASCII、WE8ISO8859P1、ZHS16GBK、AL32UTF8等。遵循以下命名规则: <Language><bit size><encoding> <语 言><比特数><编码> ZHS 16...
  • 就是建立数据库时用的是他本身的字符集 ZHS16GBK,但是我后台用的utf8,请问怎么把这个已建立的数据库字符集变为utf8呢,还是我要重新再做啊,重做的时候怎么指定字符集呢 我百度了很多,网上说要更改服务器端和...
  • oracle 字符集

    2017-12-29 11:23:38
    一、什么是Oracle字符集  Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,...
  • 本文主要讨论以下几个部分:如何查看查询oracle字符集、 修改设置字符集以及常见的oracle utf8字符集和oracle exp 字符集问题。 一、什么是Oracle字符集 Oracle字符集是一个字节数据的解释的符号集合,有大小之分,...
  • oracle字符集 Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,...
  • 导入导出及转换 ...在导出操作时,非常重要的是客户端的字符集设置,也就是客户端的NLS_LANG设置。 NLS_LANG参数由以下部分组成: NLS_LANG=_. NLS_LANG各部分含义如下: LANGUAGE指定: -O...
  • Oracle字符集专题

    2011-04-09 16:58:49
    Oracle字符集汇总,各种字符集配置,常见问题,导入导出等等,可以解决大多数Oracle字符集问题。 强烈推荐。(原创)
  • 理解Oracle数据库字符集

    千次阅读 2011-04-11 09:10:00
    数据库字符集,即Oracle 全球化支持(Globalization Support) ,或即国家语言支持(NLS )其作用是用本国语言和格式来存储、处理和检索数据。利用全球化支持,ORACLE 为用户提供自己熟悉的数据库母语环境,诸如...
  • Oracle 设置字符集

    千次阅读 2017-12-26 17:38:51
    AL32UTF8字符集不是一种可(显示/输入)的语言字符集,是一种用于存储的字符集,支持全世界主要的文字语言编码。 AL32UTF8为ZHS16GBK的超集。 NLS_LANG应该设置成系统本身所使用的语言字符集,与数据库语言...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,230
精华内容 8,492
关键字:

oracle指定字符集导出