精华内容
下载资源
问答
  • 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字符集转换

    2017-02-28 15:58:48
    作为一个Oracle数据库的用户,对于Export和Import两个命令绝对不会感到陌生,因为这 二者正是我们经常用于数据备份...Import过程中Oracle字符集的转换规律及使用这两个命令的注意事项做一总结。  字符集转换的原因
           作为一个Oracle数据库的用户,对于Export和Import两个命令绝对不会感到陌生,因为这
    
    二者正是我们经常用于数据备份和恢复的工具。但在使用这两个命令过程中所发生的Oracle字
    符集问题,常给一些Oracle使用者带来不必要的麻烦和不必要的数据损失。本文将就Export和
    Import过程中Oracle字符集的转换规律及使用这两个命令的注意事项做一总结。
      字符集转换的原因   
      Export、Import过程如上图所示,从这个示意图中可以看到有四处关系到字符集,而这四
    处字符集的不一致恰恰是导致Oracle进行字符集转换的原因。
      * 源数据库字符集;
      * Export过程中用户会话字符集;
      * Import过程中用户会话字符集;
      * 目标数据库字符集。
      在Export和Import过程中,如果存在影响字符集转换的四因素不一致,则可能发生Oracle
      在Export过程中,如果源数据库字符集与Export用户会话字符集不一致,会发生字符集转
    换,并在导出的二进制格式Dmp文件的头部几个字节中存储Export用户会话字符集的ID号。在
      例1: 如果源数据库使用ZHS16GBK,而Export用户会话字符集使用US7ASCII,由于
    ZHS16GBK是8位字符集,而US7ASCII是7位字符集,这个转换过程中,中文字符在US7ASCII中不
    能够找到对等的字符,所以所有中文字符都会丢失而变成“?? ”形式,即这种转换后生成的
      例2: 如果源数据库使用ZHS16GBK,而Export用户会话字符集使用ZHS16CGB231280,但由
    于ZHS16GBK字符集是ZHS16CGB231280字符集的超集,这个过程中绝大部分字符都能够正确转换
    ,只有一些超出ZHS16CGB231280字符集的字符变为“?? ”形式。如果源数据库使用
    ZHS16CGB231280字符集,而Export用户会话使用ZHS16GBK字符集,则转换过程能够完全转换成
      在Import向目标数据库转换过程中,其字符集发生转换的情况正好与Export过程相反,这
      在Export导出的Dmp文件中,含有Export用户会话字符集。在Import过程中,首先发生的
    是Dmp文件字符集(即Export用户会话字符集)向Import用户会话字符集的转换。如果这个转
    换过程不能正确完成,Import向目标数据库的导入过程也就不能完成。
      进行字符集的正确转换
      通常情况下,我们在使用Oracle的Export和Import过程中,并不希望发生字符的转换,但
    有时这种转换却是必要的。如我们在安装Oracle数据库时,选择ZHS16CGB231280字符集,由于
    这种字符集是一种中文小字符集,对于一些汉字不能够正确表示,这需要通过使用ZHS16GBK字
      为了确保Export、Import过程中,Oracle字符集不发生转换或正确转换,建议最好在进行
    这个过程前,检查一下源数据库字符集与Export用户会话字符集是否一致,源数据库字符集与
    目标数据库字符集是否一致,目标数据库字符与Import用户会话字符集是否一致。如果能够保
    证这四个字符集是一致的,则在Export、Import过程中,Oracle字符集就不用发生转换。
      可用以下办法检查数据库字符集:
      通过InitXXXX.ora文件进行查看;
      借助SQL语句查看: SELECT NAME,VALUE$ FROM SYS.PROPS$ WHERE NAME=‘
      对于Export、Import用户会话字符集,在Windows系统中也可以通过注册表中的NLS_LANG
    进行查看或修改,对于Unix系统则可通过设置用户的环境变量NLS_LANG来查看或修改。
      特别要注意的是,Oracle数据库字符集通常是在创建时确定,一旦存储用户数据后就不要
    再修改了,因为其数据都是使用该字符集进行存储的,改换其他字符集之后,原有数据就不能
    够正确表示了。但如果确实想进行字符集改变,则可通过以下几步来实现:
      备份数据库后删除原数据(可物理备份,如使用Export,请注意确保字符集不发生转换或
      使用Internal用户更新sys.props$表中的字符集:
      Update sys.props$ set name=‘Dest.CharSet’ Where name=‘NLS_CHARACTERSET’;
      重启数据库;
      恢复数据。
      下面字符集之间的转换是可行的:
      字符集子集向字符集父集转换是可行的,如ZHS16CGB231280向ZHS16GBK转换;而字符集父
      只包含英文字符数据的双字节字符集也可向单字节字符集转换,如ZHS16GBK(English
      编码范围相同的单字节字符集之间通常可以进行相互转换。
      请注意,这里所说的没有数据损失,是指一种字符集A转换成另一种字符集B之后,可以再
    从字符集B正确转换成字符集A或字符集B能够正确表示字符集A中转换过来的数据。
      字符集对程序的影响
      根据一个字符需要多少位字节来表示,可以把字符集分为单字节字符集和多字节字符集。
    其中,单字节字符集又分为7位字符集和8位字符集。单字节7位编码字符集有US7ASCⅡ,单字
    节8位编码字符集有符合ISO 8859-1标准规定的WE8ISO8859P1等。多字节编码又分为固定长度
    (长度大于或等于2)编码模式和不固定长度编码模式。多字节编码字符集中的ZHS16GBK、
    ZHS16CGB231280、JA16SJIS等是采用两个字节表示一个字符的字符集,又叫双字节字符集。
      一个英文字母是一个字符,一个中文汉字是几个字符呢?我们知道,一个中文汉字是双字
    节字符,但它有几个字符与其数据库字符集有关。如果数据库字符集使用单字节US7ASCII,则
    一个中文汉字是二个字符;如果数据库字符集使用双字节字符集ZHS16GBK,则一个中文汉字是
    一个字符。有关这一点可以使用Oracle的函数Substr得到证明。
      使用US7ASCⅡ字符集时:
      Select substr(‘东北大学’,1,2) from dual;
      语句执行结果返回‘东’。
      使用ZHS16GBK字符集时:
      Select substr(‘东北大学’,1,2) from dual;
      语句执行结果返回‘东北’。
      选择合适的数据库字符集
      选择数据库字符集时应考虑以下事项:
      1.数据库需要支持什么语言
      在为数据库选择字符集时,常会发现几种字符集都适合你当前语言需求,如简体中文就有
    ZHS16GBK和ZHSCGB231280等字符集可供选择,应选择哪种?在选择字符集时,应考虑到数据库
    将来的系统需求。如果知道将来数据库要扩展支持不同的语言,选择一个范围较广的字符集会
      2.系统资源与应用之间的互作用性
      选择的数据库字符集应保证操作系统与应用之间的无缝连接。如果选择的字符集不是操作
    系统有效的字符集,则系统就需要在这两者之间做字符转换。在这种字符转换过程中,就有可
    能发生一些字符丢失现象。从一种字符集A向另一种字符集B转换过程中,A中的字符必须在B中
    可以找到等价的字符,否则就会以“?”来代替。从这个意义上说,如果两种字符集编码范围
      字符集转换过程中会影响系统性能,因此,应保证客户端和服务器端有相同的字符集以避
    免字符集转换,也可以提高一定的系统性能。
      3.系统的性能要求
      不同的数据库字符集对于数据库的性能是有一定影响的。为了得到最好的数据库性能,选
    择的数据库字符集应避免字符转换,并且要选择对于期望的语言有最高效的编码效率。通常,
    单字节字符集比多字节字符集有更优的性能表现,在空间需求方面也更小些。
      4.其他一些限制
      在为数据库选择一个合适的字符集时,应参考Oracle对应版本的相关文档,检查Oracle对
    于一些字符集的限制。如Oracle 8.1.5版本中,以下字符集是不能使用的: JA16EUCFIXED、
    ZHS16GBKFIXED、JA16DBCSFIXED、KO16DBCSFIXED、ZHS16DBCSFIXED、JA16SJISFIXED、
      综上所述,正确理解Oracle字符集的转换过程,可以使我们避免不必要的麻烦和数据损失
    。合理利用Oracle字符集的转换过程,也可以帮助我们正确地从一种字符集转换到另一种字符
    集,以满足我们各种不同的应用需求。
    展开全文
  • Oracle字符集及其查看和修改

    万次阅读 2016-06-07 17:53:38
    Oracle中查看所用字符集及修改字符集。

    一、什么是Oracle字符集

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

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

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

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

    其中:

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

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

    Charset  指定字符集。

    如:AMERICAN _ AMERICA. ZHS16GBK

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

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

    二.字符集的相关知识:

    2.1 字符集
        实质就是按照一定的字符编码方案,对一组特定的符号,分别赋予不同数值编码的集合。Oracle数据库最早支持的编码方案是US7ASCII。
        Oracle的字符集命名遵循以下命名规则:
        <Language><bit size><encoding>
        
    即: <语言><比特位数><编码>
        比如: ZHS16GBK表示采用GBK编码格式、16位(两个字节)简体中文字符集 
      
    2.2 字符编码方案
    2.2.1 单字节编码
        (1)单字节7位字符集,可以定义128个字符,最常用的字符集为US7ASCII
        (2)单字节8位字符集,可以定义256个字符,适合于欧洲大部分国家
                 例如:WE8ISO8859P1(西欧、8位、ISO标准8859P1编码)

    2.2.2 多字节编码
        1)变长多字节编码
        某些字符用一个字节表示,其它字符用两个或多个字符表示,变长多字节编码常用于对亚洲语言的支持,   例如日语、汉语、印地语等
        例如:AL32UTF8(其中AL代表ALL,指适用于所有语言)、zhs16cgb231280
        2)定长多字节编码
        每一个字符都使用固定长度字节的编码方案,目前oracle唯一支持的定长多字节编码是AF16UTF16,也是仅用于国家字符集

    2.2.3 unicode编码
        Unicode是一个涵盖了目前全世界使用的所有已知字符的单一编码方案,也就是说Unicode为每一个字符提供唯一的编码。UTF-16unicode16位编码方式,是一种定长多字节编码,用2个字节表示一个unicode字符,AF16UTF16UTF-16编码字符集
        UTF-8unicode8位编码方式,是一种变长多字节编码,这种编码可以用1、2、3个字节表示一个unicode字符,AL32UTF8,UTF8、UTFE是UTF-8编码字符集 
      
    2.3 字符集超级
        当一种字符集(字符集A)的编码数值包含所有另一种字符集(字符集B)的编码数值,并且两种字符集相同编码数值代表相同的字符时,则字符集A是字符集B的超级,或称字符集B是字符集A的子集。
        Oracle8i和oracle9i官方文档资料中备有子集-超级对照表(subset-superset pairs,例如:WE8ISO8859P1是WE8MSWIN1252的子集。由于US7ASCII是最早的Oracle数据库编码格式,因此有许多字符集是US7ASCII的超集,例如WE8ISO8859P1、ZHS16CGB231280、ZHS16GBK都是US7ASCII的超集。 
      
    2.4 数据库字符集(oracle服务器端字符集)
        数据库字符集在创建数据库时指定,在创建后通常不能更改。在创建数据库时,可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。

    2.4.1字符集
        (1)用来存储CHAR, VARCHAR2, CLOB, LONG等类型数据
        (2)用来标示诸如表名、列名以及PL/SQL变量等
        (3)用来存储SQL和PL/SQL程序单元等

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

    2.4.3查询字符集参数
        可以查询以下数据字典或视图查看字符集设置情况
        nls_database_parameters、props$、v$nls_parameters
        查询结果中NLS_CHARACTERSET表示字符集NLS_NCHAR_CHARACTERSET表示国家字符集

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

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

    2. 通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8是US7ASCII的超集,修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。 
    2.5 客户端字符集(NLS_LANG参数)
    2.5.1客户端字符集含义
        客户端字符集定义了客户端字符数据的编码方式,任何发自或发往客户端的字符数据均使用客户端定义的字符集编码,客户端可以看作是能与数据库直接连接的各种应用,例如sqlplus,exp/imp等。客户端字符集是通过设置NLS_LANG参数来设定的。

    2.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是客户端字符集

    2.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

    2.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参数取值

    2.5.5修改NLS参数
        使用下列方法可以修改NLS参数
        (1)修改实例启动时使用的初始化参数文件
        (2)修改环境变量NLS_LANG
        (3)使用ALTER SESSION语句,在oracle会话中修改
        (4)使用某些SQL函数
        NLS作用优先级别:Sql function > alter session > 环境变量或注册表 > 参数文件 > 数据库默认参数

    三.EXP/IMP  字符集

    3.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)目标数据库字符集 
    3.2 导出的转换过程
        在Export过程中,如果源数据库字符集与Export用户会话字符集不一致,会发生字符集转换,并在导出文件的头部几个字节中存储Export用户会话字符集的ID号。在这个转换过程中可能发生数据的丢失。
    例:如果源数据库使用ZHS16GBK,而Export用户会话字符集使用US7ASCII,由于ZHS16GBK是16位字符集,而US7ASCII是7位字符集,这个转换过程中,中文字符在US7ASCII中不能够找到对等的字符,所以所有中文字符都会丢失而变成“?? ”形式,这样转换后生成的Dmp文件已经发生了数据丢失。
    因此如果想正确导出源数据库数据,则Export过程中用户会话字符集应等于源数据库字符集或是源数据库字符集的超集

    3.3 导入的转换过程
        (1)确定导出数据库字符集环境
                 通过读取导出文件头,可以获得导出文件的字符集设置
        (2)确定导入session的字符集,即导入Session使用的NLS_LANG环境变量
        (3)IMP读取导出文件
                 读取导出文件字符集ID,和导入进程的NLS_LANG进行比较
        (4)如果导出文件字符集和导入Session字符集相同,那么在这一步骤内就不需要转换,如果不同,就需要把数据转换为导入Session使用的字符集。可以看出,导入数据到数据库过程中发生两次字符集转换。
    第一次:导入文件字符集与导入Session使用的字符集之间的转换,如果这个转换过程不能正确完成,Import向目标数据库的导入过程也就不能完成。
    第二次:导入Session字符集与数据库字符集之间的转换。

    查看数据库字符集

    涉及三方面的字符集,

    1. oracel server端的字符集;

    2. oracle client端的字符集;

    3. dmp文件的字符集。

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

    4.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

    4.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也可以得到它对应的字符集。

    4.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的字符集

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

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

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

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

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

    1.  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 ZHS16GBK;

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

    SQL>ALTER DATABASE CHARACTER SET INTERNAL_USE AL32UTF8;

    SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE AL32UTF8;

    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的区域设置就没有问题

    5.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无法打开,就需要用程序的方法了。

    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

     或者在窗口设置:

            set nls_lang=AMERICAN_AMERICA.ZHS16GBK

    概念描述

       ORACLE数据库有国家字符集(national character set)与数据库字符集(database character set)之分。两者都是在创建数据库时需要设置的。国家字符集主要是用于NCHAR、NVARCHAR、NCLOB类型的字段数据,而数据库字符集使用很广泛,它用于:CHAR、VARCHAR、CLOB、LONG类型的字段数据;

    ORACLE的字符集名字一般由以下部分组成:语言或区域、表示一个字符的比特位数、标准字符集名称(可选项,S或C,表示服务器或客户端)。ORACLE字符集UTF8与UTFE不符合此规定,其它基本都是这种格式。NLS_LANG=<Language>_<Territory>.<Clients Characterset>

    set nls_lang=AMERICAN_AMERICA.UTF8

    set nls_lang=SIMPLIFIED CHINESE_AMERICA.UTF8

    NLS( National Language Support)国家语言支持。NLS是数据库的一个非常强大的特性,它控制着数据的许多方面:比如数据如何存储,一般来说它控制着以下两个方面:

    文本数据持久存储在磁盘上时如何编码

    透明的将数据从一个字符集转换到另外一个字符集。

    假设你在数据库中用WE8ISO8859P1 字符集存储8 位的数据,但是你的某些客户使用的是一种7 位字符集,如US7ASCII字符集转换过程通常会修改数据,而你往往会把一个较大的字符集(在此例中就是8 位字符集)映射到一个较小的字符集(此例中的7 位字符集)。这是一种有损转换(lossy conversion),字符就会被修改,这只是因为:较小的字符集不可能表示较大字符集中的每一个字符。但是这种转换必须发生。这也是乱码产生的原因。如果数据库以一种单字节字符集存储数据,但是客户(如一个Java 应用,因为Java 语言使用Unicode)希望数据采用多字节表示,就必须执行转换,只有这样客户应用才能使用这些数据。

    ORACLE支持的Unicode字符集有以下几种,下面的列表给出了字符集的名称、对应的数据库版本范围、采用的Unicode的版本。

    AL24UTFFSS:是ORACLE第一种支持Unicode的字符集,从7.2版本开始使用,但是它支持的Unicode版本为1.1,因此从9i开始就不支持此字符集了。

    UTF8 : 是ORACLE从ORACLE8开始使用的属于UTF-8编码的字符集,从ORACLE8.0到ORACLE8.16,Unicode版本为2.1,而ORACLE817到10g,采用的Unicode标 准为3.0

    UTFE :用于EBCDIC码平台上的数据库Unicode字符集。因此它属于专用系统使用的字符集,其它属性与UTF8基本相同。

    AL32UTF8 :是从ORACLE9开始使用的属于UTF-8编码的字符集,与UTF8相比,它采用的Unicode版本更新,在10g版本中使用的是Unicode 4.01标准,而UTF8因 为兼容性的考虑,在10g版本中用的是Unicode 3.0标准。

    AL16UTF16:是ORACLE第一种采用UTF-16编码方式的字符集,从ORACLE9开始使用,是作为缺省的国家字符集使用,它不能被用作数据库的字符集。这是因为数 据库的字符集决定了SQL与PL/SQL源码的编码方式,对于UTF-16这种使用固定的两个字节来表示英文字母的编码方案来说,确实不适于用作数据库 的字符集,ORACLE目前采用的数据库字符集都是基于ASCII或EBCDID作为子集的编码方案。

    对于US7ASCII,表示区域是US,用7个比特位表示一个字符,标准的字符集名称为ASCII。

    对于中文字符集ZHS16GBK,表示简体中文(ZHT为繁体中文),一个字符需要16位比特,标准的字符集名称为GBK。而ZHS16CGB231280表示简体中文,一个字符需要16位比特,标准的字符集名称为GB231280,属于我们前面提过的1981年发布的GB2312-80标准。虽然我们说,GBK编码标准是GB2312编码标准的扩展,但是数据库字符集ZHS16GBK与ZHS16CGB231280之间却不是严格的超集与子集的关系,主要是有些汉字的编码在两个字符集中的数值是不同的,因此它们进行字符集转换时会出现问题。

    查看字符集参数

    1:查看NLS_CHARACTERSET:字符集,NLS_NCHAR_CHARACTERSET:国家字符集

    实例字符集环境

    SELECT * FROM NLS_INSTANCE_PARAMETERS

    主要涉及NLS_LANGUAGE、NLS_TERRITORY的值. NLS_INSTANCE_PARAMETERS其来源于v$parameter,注意:网上很多资料都说"NLS_INSTANCE_PARAMETERS 表示客户端的字符集的设置,可以是参数文件,环境变量或者是注册表",而且网上都人人亦云。记住它是表示实例的字符集环境。

    数据库可用字符集参数设置

    SELECT * FROM V$NLS_VALID_VALUES

    数据库服务器字符集

    SELECT * FROM NLS_DATABASE_PARAMETERS

     

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

    客户端字符集环境

    SELECT * FROM V$NLS_PARAMETERS;

    SELECT USERENV('language') FROM DUAL;

    USERENV、 V$NLS_PARAMETERS表示当前字符集环境。如果你在客户端执行,则表示客户端字符集环境。

    会话字符集环境

    SELECT * FROM NLS_SESSION_PARAMETERS;

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

    2: 查看客户端字符集(NLS_LANG) 的方法

    如果系统是LINUX或UNIX平台,则也可以通过下面命令查看(前提是必须设置了NLS_LANG,否则查出来的是空值)

    [etl@m1 ~]$env | grep NLS_LANG

    NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

    [etl@m1 ~]$echo $NLS_LANG

    AMERICAN_AMERICA.ZHS16GBK

    如果系统是WINDOWS平台,则可以通过下面命令查看:

    1:在运行里面,输入regedit进入注册表,HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraDb11g_home1\里面(最后一项与实例名、数据库版本有关系),找到NLS_LANG选项,双击它,你就可以看到相应的值。

    2:echo %NLS_LANG% 。如果没有设置NLS_LANG,用这个命令看不到相关信息。

    3: 设置NLS_LANG的方法

    Windows平台:

    3.1

    set NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

    set NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

    3.2 可以通过修改注册表键值永久设置

    HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/KEY_XXXX_home1/NLS_LANG

    UNIX & LINUX

    3.3

    export NLS_LANG=AMERICAN_AMERICA.UTF8

    3.4可以编辑 bash_profile 文件进行永久设置

    vi .bash_profile

    export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"

    客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。如果多个设置存在的时候优先级关系为:SQL Function >Alter session>环境变量>注册表>参数文件 字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是American_America.zhs16gbk。

     

    修改数据库字符集

    数据库字符集在创建后原则上不能更改。因此,在前期规划和安装之初考虑使用哪一种字符集十分重要。对数据库服务器而言,错误的修改字符集将会导致很多不可测的后果,可能会严重影响数据库的正常运行,所以在修改之前一定要确认两种字符集是否存在子集和超集的关系。一般来说,除非万不得已,我们不建议修改ORACLE数据库SERVER端的字符集。

    有两种方法修改数据库字符集设置

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

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

    特别说明,我们最常用的两种字符集ZHS16GBK和ZHS16CGB231280之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持修改

    关于数据库子集-超级对照表(subset-superset pairs),可以参考官方文档,例如ORACLE 10g的http://docs.oracle.com/cd/B19306_01/server.102/b14225/applocaledata.htm

    Table A-11 Subset-Superset Pairs

    Subset

    Superset

    AR8ADOS710

    AR8ADOS710T

    AR8ADOS720

    AR8ADOS720T

    AR8ADOS720T

    AR8ADOS720

    AR8APTEC715

    AR8APTEC715T

    AR8ARABICMACT

    AR8ARABICMAC

    AR8ISO8859P6

    AR8ASMO708PLUS

    AR8ISO8859P6

    AR8ASMO8X

    AR8MUSSAD768

    AR8MUSSAD768T

    AR8MUSSAD768T

    AR8MUSSAD768

    AR8NAFITHA711

    AR8NAFITHA711T

    AR8NAFITHA721

    AR8NAFITHA721T

    AR8SAKHR707

    AR8SAKHR707T

    AR8SAKHR707T

    AR8SAKHR707

    BLT8CP921

    BLT8ISO8859P13

    BLT8CP921

    LT8MSWIN921

    D7DEC

    D7SIEMENS9780X

    D7SIEMENS9780X

    D7DEC

    DK7SIEMENS9780X

    N7SIEMENS9780X

    I7DEC

    I7SIEMENS9780X

    I7SIEMENS9780X

    IW8EBCDIC424

    IW8EBCDIC424

    IW8EBCDIC1086

    KO16KSC5601

    KO16MSWIN949

    LT8MSWIN921

    BLT8ISO8859P13

    LT8MSWIN921

    BLT8CP921

    N7SIEMENS9780X

    DK7SIEMENS9780X

    US7ASCII

    See Table A-12, "US7ASCII Supersets".

    UTF8

    AL32UTF8

    WE8DEC

    TR8DEC

    WE8DEC

    WE8NCR4970

    WE8ISO8859P1

    WE8MSWIN1252

    WE8ISO8859P9

    TR8MSWIN1254

    WE8NCR4970

    TR8DEC

    WE8NCR4970

    WE8DEC

    WE8PC850

    WE8PC858

       1: SQL>CONN / AS SYSDBA;
       2: SQL>SHUTDOWN IMMEDIATE;
       3: SQL>STARTUP MOUNT;
    
       4: SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION; 
       5: SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
    
       6: SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0;
    
       7: SQL>ALTER DATABASE OPEN;

    --可以从子集到父集

       1: SQL>ALTER DATABASE CHARACTER SET ZHS16GBK;
    
       2: --如果是从父集到子集,需要使用INTERNAL_USE参数,跳过超子集检测
    
       3: SQL>ALTER DATABASE NATIONAL CHARACTER SET UTF8;
    
       4: --SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8;
    
       5: SQL>SHUTDOWN IMMEDIATE;
    
       6: SQL>STARTUP;

    ALTER DATABASE NATIONAL CHARACTER SET UTF8;

    有可能会出现ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when NCLOB data exists 这样的提示信息.这时你用ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8;就可解决上述问题。

    基本概念

    字符集(Character set):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。常见的字符集有ASCII,ZHS16GB231280,ZHS16GBK等。

    字符编码(Character Encoding):是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其它的一个集合(如电脑编码)进行配对。即在符号集合与数字系统之间建立对应关系。与字符集相对应,常见的字符编码有:ASCii,ZHS16GBK,ZHT16BIG5,ZHS32GB18030等。
    字符集的定义其实就是字符的集合,而字符编码则是指怎么将这些字符变成字节用于保存、读取和传输。

    万国码(Unicode):包含了几乎人类所有可用的字符,每年还在不断的增加,可以看作是一种通用的字符集。它将全世界所有的字符统一化,统一编码,不会再出现字符不兼容和字符转换的问题。
    它有以下三种编码方式:
    1.UTF-32编码:
    固定使用4个字节来表示一个字符,存在空间利用效率的问题。
    2.UTF-16编码:对相对常用的60000余个字符使用两个字节进行编码,其余的使用4字节。
    3.UTF- 8编码:兼容ASCII编码;拉丁文、希腊文等使用两个字节;包括汉字在内的其它常用字符使用三个字节;剩下的极少使用的字符使用四个字节。

    Oracle字符集基本原理
    在搞懂Oracle字符集基本原理之前,一定要先分清以下三个概念:
    1. Oracle数据库服务器字符集:即Oracle以哪种字符编码存储字符,可以通过以下语句查出数据库字符集的设置。

    复制代码 代码如下:

    SQL> select * from v$nls_parameters where parameter='NLS_CHARACTERSET';
    PARAMETER                      VALUE
    ------------------------------ -----------------
    NLS_CHARACTERSET               AL32UTF8


    2. 客户端操作系统字符集:即客户端操作系统以哪种字符编码存储字符。
    如果是Windows,可以使用chcp命令获得代码页(code page):

    代码如下:

     


    C:\Users\xianzhu>chcp
    Active code page: 936


    根据该代码页,到微软的官方文档《National Language Support (NLS) API Reference》找到其对应的字符集。
    如果是Linux,字符集在/etc/sysconfig/i18n设置:

    代码如下:

    LANG="zh_CN.GB2312" (指定当前操作系统的字符集)
    SUPPORTED="zh_CN.GB2312"(指定当前操作系统支持的字符集)
    SYSFONT="lat0-sun16"(指定当前操作系统的字体)

    3. 客户端NLS_LANG参数:该参数用于向Oracle指示客户端操作系统的字符集。
    有了以上3个基本概念之后,我来阐述一下Oracle字符集转换的基本原则:
    1.设置客户端的NLS_LANG为客户端操作系统的字符集
    2.如果数据库字符集等于NLS_LANG,数据库和客户端传输字符时不作任何转换
    3.如果它们俩不等,则需要在不同字符集间转换,只有客户端操作系统字符集是数据库字符集子集的基础上才能正确转换,否则会出现乱码。
    几种常见情况分析
    下面先看一个例子,再透过现象看本质,我们会针对这个例子进行分析。
    该例子如下:

    代码如下:

    1. 数据库字符集为Unicode(UTF-8编码)
    我们的数据库版本是10.2.0.4.0,数据库字符集是:
    SQL> select * from v$nls_parameters where parameter='NLS_CHARACTERSET';
    PARAMETER                                VALUE
    ---------------------------------------- ------------------------------
    NLS_CHARACTERSET               AL32UTF8
    2. 客户端操作系统字符集为代码页936(字符集为ZHS16GBK)
    可以使用chcp获得windows的代码页(code page)
    C:\Documents and Settings\a105024\Desktop>chcp
    Active code page: 936
    3. 创建测试表
    SQL> create table test(id number,var varchar2(30));
    Table created.
    4. 插入数据
    这里在同一个操作系统启动两个session,session1的NLS_LANG设为和数据库字符集一样(即AL32UTF8):
    C:\Documents and Settings\a105024\Desktop>set nls_lang=Simplified Chinese_China.AL32UTF8
    连接数据库并插入一条数据:
    Session_1>insert into test values(1,'中国');
    1 row created.
    Session_1>commit;
    Commit complete.
    session2的NLS_LANG设为和客户端操作系统一样(即ZHS16GBK):
    C:\Documents and Settings\a105024\Desktop>set nls_lang=Simplified Chinese_China.ZHS16GBK
    连接数据库并插入一条数据:
    Session_2>insert into test values(2,'中国');
    1 row created.
    Session_2>commit;
    Commit complete.
    5. 执行查询
    在session 1上执行查询:
    Session_1>select * from test;
            ID VAR
    ---------- ---------------------
             1 中国
             2 涓   浗
    在session 2上执行查询:
    Session_2>select * from test;
            ID VAR
    ---------- --------------------
             1 ???
             2 中国

    上面例子看起来很诡异,session1和2都能正常显示自己插入的字符串,又都不能正常显示对方插入的字符串。为了弄清楚,我们首先得知道数据库里对这两个字符串是怎么存储的。我们可以使用dump函数获得字符在数据库的编码:

    代码如下:

    SQL> select id,dump(var,1016) from test;
    ID DUMP(VAR,1016)
    -- ------------------------------------------------------------
     1 Typ=1 Len=4 CharacterSet=AL32UTF8: d6,d0,b9,fa
     2 Typ=1 Len=6 CharacterSet=AL32UTF8: e4,b8,ad,e5,9b,bd

    根据AL32UTF8的编码,“中国”两字的正确编码为(都为3个字节):
    中--e4,b8,ad
    国--e5,9b,bd
    因此session 1插入的字符串在数据库中的编码是错误的,session 2正确。这也是为什么一定要设置NLS_LANG为客户端操作系统的字符集。
    但是根据上面实验我们可以知道,数据库中存储正确,并不代表客户端能正常显示;同样地,即时数据库没有正确存储,有时候客户端也能够正常显示,这又是为什么呢?别急,请听我慢慢道来:

    场景1:session 1插入,session 1查询,在数据库中存储错误,但显示正确。
    插入过程:
    ”中国“两字在客户端操作系统字符集ZHS16GBK中的编码是”d6,d0,b9,fa",由于NLS_LANG和数据库字符集相同,数据库端对客户端传过来的字符编码不进行任何转换直接存入数据库,因此数据库中存储的编码也是“d6,d0,b9,fa”,
    读取过程:
    数据库端读取的编码是“d6,d0,b9,fa”,由于NLS_LANG和数据库字符集相同,客户端对数据库端传过来的字符编码不进行任何转换直接显示,编码”d6,d0,b9,fa“在客户端操作系统字符集ZHS16GBK对应的汉字为“中国”。

    从以上分析可知,虽然读取时正确的,但那是因为负负得正,实际上数据库中存储是错误的,因此要特别小心这种情况,在生成库中要避免。其实只要对它进行length操作就能轻易揭开它的假面具:

    代码如下:

    Session_1>select length(var) from test where id=1;
    LENGTH(VAR)

    得出的长度居然为3!实际的长度只是2,这会带来很多麻烦。

    场景2:session 1插入,session 2查询,在数据库中存储错误,显示也错误。
    插入过程和场景1一样,这里就不再累述。
    读取过程:
    数据库端读取的编码是“d6,d0,b9,fa”,由于NLS_LANG和数据库字符集不同,客户端对数据库端传过来的字符编码进行转换,数据库端字符集AL32UTF8里编为“d6,d0,b9,fa”无法在客户端操作系统字符集ZHS16GBK里找到对应的编码,所以只好用?代替。

    场景3:session 2插入,session 1查询,在数据库中存储正确,但显示错误。
    插入过程:
    ”中国“两字在客户端操作系统字符集ZHS16GBK中的编码是”d6,d0,b9,fa",由于NLS_LANG和数据库字符集不同,Oracle会进行字符编码转换,也就是将字符集ZHS16GBK里“中国”的编码“d6,d0,b9,fa"转换为字符集"AL32UTF8"里”中国“的编码”e4,b8,ad,e5,9b,bd“。
    读取过程:
    数据库端读取的编码是”e4,b8,ad,e5,9b,bd“,由于NLS_LANG和数据库字符集相同,客户端对数据库端传过来的字符编码不进行任何转换直接显示,编码”e4,b8,ad,e5,9b,bd“在客户端操作系统字符集ZHS16GBK对应的汉字为“涓   浗”(原本2个字符,现在变成了3个字符,因为ZHS16GBK的汉字以2个字节编码)。

    场景4:session 2插入,session 2查询,在数据库中存储正确,显示也正确。
    插入过程和场景3类似。
    读取过程:
    数据库端读取的编码是”e4,b8,ad,e5,9b,bd“,由于NLS_LANG和数据库字符集不同,客户端对数据库端传过来的字符编码进行转换,数据库端字符集AL32UTF8里”中国“两字的编码”e4,b8,ad,e5,9b,bd“转换成客户端操作系统字符集ZHS16GBK里“中国”两字的编码“d6,d0,b9,fa",并正常显示。
    这种情况虽然经过了两次转换,都确实最正确、最推荐的方式。

    附录:Oracle 字符集超集和子集的对应关系可查看:http://download.oracle.com/docs/cd/B19306_01/server.102/b14225/applocaledata.htm#sthref1988

    结论:NLS_LANG只和客户端操作系统的字符集相关,如果客户端操作系统的字符集和数据库字符集间无法正确转换,则应该首先改变客户端终端的字符集,而不是简单地把NLS_LANG设为和数据库字符集一样。

     

     

     

    展开全文
  • 练习字符处理函数(数据库表都是从1开始),我们用到一张“伪表” dual: dual 表:dual 是一张只有一个字段,一行记录的表。dual 表也称之为'伪表',因为他不存储主题数据。如果我们不需要从具体的表来取得表中...

    练习字符处理函数(数据库表都是从1开始),我们用到一张“伪表” dual:

    dual dual 是一张只有一个字段,一行记录的表。dual 表也称之为'伪表',因为他不存储主题数据。如果我们不需要从具体的表来取得表中数据,而是单纯地为了得到一些我们想得到的信息,并要通过 select 完成时,就要借助 dual 表来满足结构化查询语言的格式。

     

     

    CONCAT(arg1,arg2):连接值在一起 (CONCAT 函数有两个输入参数)

    arg1字符串类型。字符拼接的值。

    arg2字符串类型。字符拼接的值。

    SQL> select concat('yxf','wj') from dual;
    

     

     

    SUBSTR(arg1,arg2,arg3):截取子串(如果没有arg3,则是默认从arg2截取到末尾)。

    arg1字符串类型。原字符串,

    arg2整数类型。开始位置(开始位置可以是一个负数,-1 表示原串的最后一位,-2 则表示倒是第二位以此类推)

    arg3整数类型。截取个数。

    SQL> select substr('yxfbjsxt',1,5) from dual;

    SQL> select substr('yxfbjsxt',-1,5) from dual;

    SQL> select substr('yxfbjsxt',1) from dual;

     

     

    LENGTH(arg1):以数字值显示一个字符串的长度。

    arg1字符串类型。计算长度的字符串。

    SQL> select length('yxfbjsxt') from dual;
    

     

     

    INSTR(arg1,arg2):找到一个给定字符的数字位置(没找到则返回0)。

    arg1字符串类型。原字符串。

    arg2字符串类型。查找内容。

    SQL> select instr('yxfbjsxt','wj') from dual;

    SQL> select instr('yxfbjsxt','sxt') from dual;

     

     

    INSTR(arg1,arg2,arg3,arg4):指定查找位置以及出现的次数。

    arg1字符串类型。原字符串。

    arg2字符串类型。查找内容。

    arg3整数类型。开始位置。

    arg4整数类型。第几次出现。

    SQL> select instr('yxfbjsxt','x',1,2) from dual;
    

     

     

    LPAD(arg1,arg2,arg3):用给定的字符左填充字符串到给定的长度。

    arg1字符串类型。原字符串。

    arg2整数类型。总长度。

    arg3字符串类型。填充的子字符串。

    SQL> select lpad('yxfbjsxt',9,'250') from dual;

    SQL> select lpad('yxfbjsxt',20,'250') from dual;
    

     

     

    RPAD(arg1,arg2,arg3):用给定的字符右填充字符串到给定的长度。

    arg1字符串类型。原字符串。

    arg2整数类型。总长度。

    arg3字符串类型。填充的子字符串。

    SQL> select rpad('yxfbjsxt',20,'250') from dual;
    

     

    TRIM(arg1):从一个字符串中去除头(leading)或尾(trailing)或头尾两侧(both)的字符 (默认为头尾两侧) 如果 trim_character trim_source 是一个文字字符,必须放在单引号中。

    arg1 需要操作的字符串FROM 为关键字。

    格式 1:需要去掉的内容 FROM 原字符串

    SQL> select trim('h' from 'hellhowdh') from dual;

    格式 2leading|trailing|both 需要去掉的内容 FROM 原字符串(both的用法和上面的用法是一样的,上面就是默认波让后用                   法,去除头尾。)。

    去头:

    SQL> select trim(leading 'h' from 'hellhowdh') from dual;

    去尾:

    SQL> select trim(trailing 'h' from 'hellhowdh') from dual;

     

     

     

    实例1:显示所有工作岗位名称从第 4 个字符位置开始包含字符串 REP 的雇员的信息,将雇员的姓和名连接显示在一起,还显                 示雇员名的长度,以及名字中字母 a 的位置。

    SQL> select concat(first_name,Last_name),length(last_name),instr(last_name,'a') from employees where substr(job_id,4)='REP';
    

    解析:先看题目中的需要显示的信息:1.雇员的姓和名连接显示在一起   2.显示雇员名的长度 3.名字中字母 a 的位置 这三个是我们需要提取的显示信息。然后确定是从哪张表查,最后用where子句去完成的查询要求:工作岗位名称从第 4 个字符位置开始包含字符串 REP 的雇员的信息。

     

     

    实例2:显示名字是以 n 结束的雇员的数据,将雇员的姓和名连接显示在一起,还显示雇员名的长度,以及名字中字母 a 的位                   置。(以n结尾,有俩种方法去查找。1.用模糊查询 ‘%n’,2.用字符截取函数,只截取最后一个字母                                                   substr(last_name,-1)).

    SQL> select concat(first_name,last_name) "name",length(concat(first_name,last_name)),instr(concat(first_name,last_name),'a') from employees where last_name like '%n';
    
    SQL> select concat(first_name,last_name) "姓名:",length(concat(first_name,last_name)) "姓名长度:",instr(concat(first_name,last_name),'a') "姓名中a,出现的位置:" from employees where substr(last_name,-1)='n';
    

    解析:首先明确显示的的内容:1.雇员的姓和名连接显示在一起 2.显示雇员名的长度 3.名字中字母 a 的位置。。再用where子句去查询对雇员的要求。显示名字是以 n 结束的雇员的数据。

     

    实例3:将手机号中间四位用星号代替。

    select replace(PHONE_NUMBER ,substr(PHONE_NUMBER ,5,4),'****') from employees;

    解析:用到了嵌套函数:代替肯定是需要用replace函数,在replace函数中嵌套一个substr截取函数。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • [Oracle] 搞懂Oracle字符

    千次阅读 2013-06-24 10:18:27
    基本概念 字符集(Character set):是一个系统支持的所有抽象...字符编码(Character Encoding):是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其它的一个集合(如电脑编码
  • Oracle字符集、编码

    2015-04-29 22:58:49
    HANDBOOK系列之十:字符集、编码以及Oracle的那些事 第一部分字符集与编码常识 字符集: 人们根据需要把某些字符收集到一处,并赋以名称,于是便有了某某字符集。 编码: 当前面收集的工作完成以后,...
  • oracle 字符串操作

    2020-02-19 13:28:28
    返回将(所有出现的)from_str中的每个字符替换为to_str中的相应字符以后的string。TRANSLATE 是 REPLACE 所提供的功能的一个超集。如果 from_str 比 to_str 长,那么在 from_str 中而不在 to_str 中的额外字符将从 ...
  • oracle 字符函数

    千次阅读 2011-03-12 12:48:00
    1.ASCII(x):返回与字符x对应的ASCII码; SQL> select ascii('A') A,ascii('a') a,ascii('0') zero,ascii(' ') space from dual; A A ZERO SPACE --------- --------- --------- --------- 65 97
  • Oracle字符集 彻底搞懂 字符集

    千次阅读 2016-08-17 08:35:11
    以下是对Oracle中的字符集进行了详细的分析介绍,需要的朋友可以参考下   基本概念 字符集(Character set):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形...
  • C#开发,含源码,可根据实际需要而改动代码,编译成自己定制的工具。工具代替人,效率会提高很多,且工具在于反复使用,用得越多,创造的价值越多,需要的请拿去!
  • ORACLE数据库字符集包括两部分:数据库字符集和客户端字符集. 查看数据库字符集:   SQL&gt; select * from nls_database_parameters a where a.PARAMETER in ('NLS_LANGUAGE','NLS_CHARACTERSET','NLS_...
  • Oracle 字符类型整理

    千次阅读 2012-08-11 10:32:24
    定长格式字符串,在数据库中存储时不足位数填补空格,它的声明方式如下CHAR(L),L为字符串长度,缺省为1,最大为2000。不建议使用,会带来不必要的麻烦。 a、字符串比较的时候,如果不注意(char不足位补空格)会...
  • Oracle字符集讨论(转)
  • oracle字符集深入研究

    千次阅读 2013-12-04 23:52:31
    今天是2013-12-04,今天深入研究一下oracle字符集的问题。  以前自己也遇到过 在使用exp/imp导出导入数据的时候存在乱码的情况,也在终端查看数据的时候显示乱码的情况,今天这篇笔记给自己拨开迷雾,在此感谢分享...
  • informix Oracle 字符类型比较整理

    千次阅读 2009-08-05 09:40:00
    informix oracle字符数据类型 在informix中有如下几种对字符串操作的类型: char(character),varchar,nchar,nvarchar,lvarchar,text在ORACLE中有如下几种对字符串操作的类型: char(character),varchar(varchar2)...
  • 彻底搞懂Oracle字符

    千次阅读 2016-12-31 10:47:29
    以下是对Oracle中的字符集进行了详细的分析介绍,需要的朋友可以参考下   基本概念 字符集(Character set):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号...
  • oracle字符集和编码

    千次阅读 2014-01-02 11:35:04
    字符集简介 一、字符集 作用:可以使数据库工具,...UTF-8、UTF-16、UCS-2是标准的Unicode字符集,即是使用UTF-8或UTF-16或UCS-2来实现编码,UTF8指的是Oracle中的字符集,使用UTF-8来编码 AL32UTF8、AL16UTF8是Orac
  • oracle字符串函数

    千次阅读 2008-03-24 14:09:00
    单行字符串函数 单行字符串函数用于操作字符串数据,他们大多数有一个或多个参数,其中绝大多数返回字符串 ascii() c1是一字符串,返回c1第一个字母的ascii码,他的逆函数是chr()select ascii(a) big_a,ascii(z) ...
  • oracle常用字符函数

    2014-08-19 07:40:06
    oracle中,常见的字符函数有 UPPER(列|字符串):将字符串的内容全部转换为大写 LOWER(列|字符串):将字符串的内容全部转换为小写 INITCAP(列|字符串):将字符串首字母大写 LENGTH(列|字符串):字符串长度 ...
  • 但在使用这两个命令过程中所发生的Oracle字符集问题,常给一些Oracle使用者带来不必要的麻烦和不必要的数据损失。本文将就Export和Import过程中Oracle字符集的转换规律及使用这两个命令的注意事项做一总结。  字符...
  • 一、语法: TRANSLATE(string,from_str,to_str) 参数1:string,原始字符串参数2:from_str,需要被替换的字符串参数3:to_str,用于替代from_str的字符串规则说明:string: 代表一串字符,from_str与 to_str是从左...
  • oracle字符串函数收藏

    千次阅读 热门讨论 2008-09-29 14:03:00
    单行字符串函数 单行字符串函数用于操作字符串数据,他们大多数有一个或多个参数,其中绝大多数返回字符串 ascii(c1) c1是一字符串,返回c1第一个字母的ascii码,他的逆函数是chr()select ascii(a) big_a,ascii(z...
  • oracle 12c 代替引用符(q)

    千次阅读 2018-05-23 18:55:00
    oracle 12c 代替引用符(q) 当文字列中包含' ,我们应该如何解决。 方法1 q 代替引用符 q'引用符 ... 引用符' 任意单字节和多字节字符集 [ ], { },( ) ,&amp;amp;lt;&amp;amp;gt; 各种组合。 ...
  • sybase与oracle 字符串类型长度

    千次阅读 2010-08-09 20:30:00
    转自http://tech.ddvip.com/2007-09/118966372234359.html在字符长度一定时char的性能比varchar好,而在长度不确定时,char类型的字段在...(20),表示你存储的字符将占20个字节(包括17个空字符),而同样的varchar2
  • ORACLE 字符串聚合函数 strcat

    千次阅读 2013-07-09 16:10:00
    create or replace type strcat_type as object ( currentstr varchar2(4000), currentseprator varchar2(8), static function ODCIAggregateInitialize(sctx IN OUT strcat_type) return number, ...
  • Oracle字符数据类型及存储方式

    千次阅读 2012-10-29 15:05:33
    ORACLE 10G为基础,介绍oralce 10g引入的新的数据类型。让你对oracle数据类型有一个全新的认识。揭示一些不为人知的秘密和被忽略的盲点。从实用和优化的角度出发,讨论每种数据类型的特点。从这里开始or
  • 通过全球支持,Oracle可以支持多种语言及字符集,得以展示数据库的强大魅力。由于不同语言及字符集的共同存储存在设置上具有一定的复杂性,字符集一度成为普遍困扰大家的一个主要问题。本文试图就一些常见问题进行...
  • Oracle特殊字符查询

    万次阅读 2011-09-29 14:36:20
    Oracle查询中包含特殊的字符分别为%,_,&,想查询某数据表某字段的包含这种特殊字符的内容,需要使用转义字符,或者拼接字符串的方法。 0.原数据 select * from t_web_groups where groupid=10088; --------------

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 45,255
精华内容 18,102
关键字:

oracle字符代替