刚在网上搜了些文章 可还是感觉自己对这个字符集理解的不够透彻 如果哪位有好点的文章给推荐一份吧先来说说现在碰到的问题吧 如下面代码所示
C:\Documents and Settings\Admin>chcp
活动的代码页: 936
C:\Documents and Settings\Admin>set nls_lang=AMERICAN_AMERICA.UTF8C:\Documents and Settings\Admin>sqlplus "/ as sysdba"SQL*Plus: Release 10.2.0.1.0 - Production on Fri Oct 23 13:28:24 2009Copyright (c) 1982, 2005, Oracle.  All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> create table tt(name varchar2(100));Table created.SQL> insert into tt values('一');1 row created.SQL> insert into tt values('二');1 row created.SQL> commit;Commit complete.SQL> select * from tt;NAME
--------------------------------------------------------------------------------一
二SQL>
SQL> Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
 - Production
With the Partitioning, OLAP and Data Mining optionsC:\Documents and Settings\Admin>set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBKC:\Documents and Settings\Admin>sqlplus "/ as sysdba"SQL*Plus: Release 10.2.0.1.0 - Production on 星期五 10月 23 13:29:49 2009Copyright (c) 1982, 2005, Oracle.  All rights reserved.
连接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining optionsSQL> select * from tt;NAME
--------------------------------------------------------------------------------?
??SQL> insert into tt values('三');已创建 1 行。SQL> insert into tt values('四');已创建 1 行。SQL> commit;提交完成。SQL> select * from tt;NAME
--------------------------------------------------------------------------------?
??

四SQL>
SQL> 从 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options 断开C:\Documents and Settings\Admin>set nls_lang=AMERICAN_AMERICA.UTF8C:\Documents and Settings\Admin>sqlplus "/ as sysdba"SQL*Plus: Release 10.2.0.1.0 - Production on Fri Oct 23 13:30:27 2009Copyright (c) 1982, 2005, Oracle.  All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining optionsSQL> select * from tt;NAME
--------------------------------------------------------------------------------一


鍥SQL>
1、
用chcp显示出来的936应该代表的是我操作系统的字符集吧?2、
为什么
用SIMPLIFIED CHINESE_CHINA.ZHS16GBK插入的数据在UTF8下显示不出来
用UTF8插入的数据在set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK后也显示不出来
一个显示乱码  一个显示问号?3、
我的环境是WINDOWS XP+ORACLE 10GR2
记得前几天看EYGLE的一本书上写着字符集分三个
数据库字符集 客户端字符集 客户端应用字符集 
那SQL*PLUS算是客户端还是客户端应用呢SQL> select * from nls_database_parameters;PARAMETER                      VALUE
------------------------------ ------------------------------
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               UTF8
NLS_CALENDAR                   GREGORIAN
NLS_DATE_FORMAT                DD-MON-RR
NLS_DATE_LANGUAGE              AMERICAN
NLS_SORT                       BINARY
NLS_TIME_FORMAT                HH.MI.SSXFF AMPARAMETER                      VALUE
------------------------------ ------------------------------
NLS_TIMESTAMP_FORMAT           DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT             HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT        DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY              $
NLS_COMP                       BINARY
NLS_LENGTH_SEMANTICS           BYTE
NLS_NCHAR_CONV_EXCP            FALSE
NLS_NCHAR_CHARACTERSET         UTF8
NLS_RDBMS_VERSION              10.2.0.1.020 rows selected.SQL>
注册表里所有的NLS_LANG都设置的是AMERICAN_AMERICA.UTF8希望通过这个帖子能让我彻底搞清楚字符集~大家帮帮忙~

解决方案 »

  1.   

    1.是。
    2.两个编码方式长度都不一样。不是乱码倒怪了。
    3.总之就是用你os的nls_lang环境变量中的字符集设置值。
      

  2.   

    第二点和第三点能讲得详细点吗不是说如果ORACLE发现服务器端和客户端的字符集不一致的时候会自动进行转换的么
      

  3.   

    是的。但是oracle是怎么发现“服务器端和客户端的字符集不一致”的呢?
    就是通过你设置的nls_lang参数中的字符集参数和数据库字符集对比知道的。
    你把两者设置成一样,而os实际又没用nls_lang所指的字符集。这时insert数据的字符集就会出问题了。
    具体你可以select name,dump(name) from t;看看。
      

  4.   

    先问个问题哦
    注册表里的那些NLS_LANG和我在命令行下set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK有什么关联吗?如你所说,ORACLE是通过NLS_LANG来判断客户端和数据库字符集是否一致的。那么ORACLE是通过我在命令行里SET的NLS_LANG还是根据注册表中的NLS_LANG呢?二者间存在什么优先级关系吗?呵呵 不要嫌麻烦哦 
      

  5.   

    SQL> select name,dump(name) from tt;NAME                 DUMP(NAME)
    -------------------- ------------------------------
    一                    Typ=1 Len=2: 210,187
    二                   Typ=1 Len=2: 182,254
    涓?                  Typ=1 Len=3: 228,184,137
    鍥?                  Typ=1 Len=3: 229,155,155
      

  6.   

    5L的问题你自己搜搜吧。给你的那个查询sql你要最好在两种nls_lang下插入相同的数据后,再执行。这样你就会发现在数据库的相同字符集下,相同的插入字符却有完全不同的编码。这就是乱码的原因。
      

  7.   

    C:\Documents and Settings\Admin>set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBKC:\Documents and Settings\Admin>sqlplus "/ as sysdba"SQL*Plus: Release 10.2.0.1.0 - Production on 星期五 10月 23 16:14:37 2009Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    连接到:
    Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
    With the Partitioning, OLAP and Data Mining optionsSQL> select * from tt;NAME
    --------------------------------------------------------------------------------?
    ??

    四SQL> insert into tt values('一');已创建 1 行。SQL> insert into tt values('二');已创建 1 行。SQL> commit;提交完成。
    SQL> select name,dump(name) from tt;NAME                           DUMP(NAME)
    ------------------------------ ------------------------------
    ?                             Typ=1 Len=2: 210,187
    ??                             Typ=1 Len=2: 182,254
    三                             Typ=1 Len=3: 228,184,137
    四                             Typ=1 Len=3: 229,155,155
    一                             Typ=1 Len=3: 228,184,128
    二                             Typ=1 Len=3: 228,186,140已选择6行。好的 谢谢回答~呵呵 我自己再想想
      

  8.   

    这里很好解释呀一个一个来
    实验一
    C:\Documents and Settings\Admin>set nls_lang=AMERICAN_AMERICA.UTF8
    和你数据库的代码一致了。所以这个过程Oracle将不会转码,你输入一个中文,你的系统是GBK的编码,又不发生转码,原封不动的过去了,所以你看到的 dump(name)时候,第一二两条记录都是2个字节。虽然你的Oracle客户端是UTF8.
    -------------------- ------------------------------
    一                    Typ=1 Len=2: 210,187
    二                   Typ=1 Len=2: 182,254实验二,同上理,
    你这次是set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK和数据库不一致了,将把GBK转为UTF8,也就是2个字节变3个字节。 
    也就是
    三                             Typ=1 Len=3: 228,184,137
    四                             Typ=1 Len=3: 229,155,155实验三
    第三次存的时候,和实验二一样
    所以
    一                             Typ=1 Len=3: 228,184,128
    二                             Typ=1 Len=3: 228,186,140
      

  9.   


    上面是你实验 的结果, 完全是合理的,下面我们来解释一下,为什么有时候select是乱码,有时有时正常的,完全把你都搞糊涂了。
      

  10.   

    本帖最后由 inthirties 于 2009-10-23 22:47:31 编辑
      

  11.   

    自己对字符集方面的知识还是比较匮乏的老大有没有什么好的文章推荐一份呀?
    就比如说各种字符集的编码规则(比如说用2个字节还是3个字节...),他们之间的范围关系(比如说谁是谁的超级,谁是谁的子集),还有他们的转换关系(比如说从A到B可以转,而从B到A转就会出现乱码)我刚才搜了下没搜到太好的  我再去搜搜看 不过马上就熄灯了  呵呵
      

  12.   

    我觉得自己讲的很清楚了呀,星期一看我的blog吧。
      

  13.   

    呵呵 你是讲的很清楚了呀
    可是这里只涉及到了UTF8和GBK嘛 
    我的意思就是说还有些其他字符集之间的关系之类的