先来说说现在碰到的问题吧 如下面代码所示
C:\Documents and Settings\Admin>chcp
活动的代码页: 936
C:\Documents and Settings\Admin>set nls_lang=AMERICAN_AMERICA.UTF8
C:\Documents and Settings\Admin>sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on Fri Oct 23 13:28:24 2009
Copyright (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 options
C:\Documents and Settings\Admin>set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
C:\Documents and Settings\Admin>sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on 星期五 10月 23 13:29:49 2009
Copyright (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 options
SQL> 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.UTF8
C:\Documents and Settings\Admin>sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on Fri Oct 23 13:30:27 2009
Copyright (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> 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 AM
PARAMETER 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.0
20 rows selected.
SQL>
注册表里所有的NLS_LANG都设置的是AMERICAN_AMERICA.UTF8
希望通过这个帖子能让我彻底搞清楚字符集~大家帮帮忙~
19 个解决方案
#1
1.是。
2.两个编码方式长度都不一样。不是乱码倒怪了。
3.总之就是用你os的nls_lang环境变量中的字符集设置值。
2.两个编码方式长度都不一样。不是乱码倒怪了。
3.总之就是用你os的nls_lang环境变量中的字符集设置值。
#2
关注,学习
#3
第二点和第三点能讲得详细点吗
不是说如果ORACLE发现服务器端和客户端的字符集不一致的时候会自动进行转换的么
不是说如果ORACLE发现服务器端和客户端的字符集不一致的时候会自动进行转换的么
#4
是的。但是oracle是怎么发现“服务器端和客户端的字符集不一致”的呢?
就是通过你设置的nls_lang参数中的字符集参数和数据库字符集对比知道的。
你把两者设置成一样,而os实际又没用nls_lang所指的字符集。这时insert数据的字符集就会出问题了。
具体你可以select name,dump(name) from t;看看。
#5
先问个问题哦
注册表里的那些NLS_LANG和我在命令行下set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK有什么关联吗?
如你所说,ORACLE是通过NLS_LANG来判断客户端和数据库字符集是否一致的。那么ORACLE是通过我在命令行里SET的NLS_LANG还是根据注册表中的NLS_LANG呢?二者间存在什么优先级关系吗?
呵呵 不要嫌麻烦哦
注册表里的那些NLS_LANG和我在命令行下set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK有什么关联吗?
如你所说,ORACLE是通过NLS_LANG来判断客户端和数据库字符集是否一致的。那么ORACLE是通过我在命令行里SET的NLS_LANG还是根据注册表中的NLS_LANG呢?二者间存在什么优先级关系吗?
呵呵 不要嫌麻烦哦
#6
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
#7
5L的问题你自己搜搜吧。
给你的那个查询sql你要最好在两种nls_lang下插入相同的数据后,再执行。这样你就会发现在数据库的相同字符集下,相同的插入字符却有完全不同的编码。这就是乱码的原因。
给你的那个查询sql你要最好在两种nls_lang下插入相同的数据后,再执行。这样你就会发现在数据库的相同字符集下,相同的插入字符却有完全不同的编码。这就是乱码的原因。
#8
C:\Documents and Settings\Admin>set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
C:\Documents and Settings\Admin>sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on 星期五 10月 23 16:14:37 2009
Copyright (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 options
SQL> 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行。
好的 谢谢回答~呵呵 我自己再想想
#9
这里很好解释呀
一个一个来
实验一
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
一个一个来
实验一
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
#10
上面是你实验 的结果, 完全是合理的,下面我们来解释一下,为什么有时候select是乱码,有时有时正常的,完全把你都搞糊涂了。
#11
关键是实验二
怎么我用SIMPLIFIED CHINESE_CHINA.ZHS16GBK的时候,看到了乱码,但是存进去却不是乱码。究竟是怎么回事呀。
我们来看 一,二两条记录,根据上面的回答,我们知道一,二进去的时候,没有转码,所以两个字节。 我们现在来显示,由于客户端是SIMPLIFIED CHINESE_CHINA.ZHS16GBK,和服务器不一致,这时候,服务器和客户端知道要转码了。由UTF8致GBK, 很显然,这里转是有错误的,所以一,二是乱码了。
在来看三 四, 三,四是在GBK的情况下进去的,这时候很显然了,不一致要转码,中文转为utf8,三个字节,显示的时候,一样的,不一致,要转码,本来进去就是utf8进去的,转成GBK当然没有问题了,所以也就正常显示了。
在看实验三
为什么我们set nls_lang=AMERICAN_AMERICA.UTF8后,再看刚刚做进去的三 四又乱码叻。
还是字符集的秘密,这是和服务器一致,不会转码,
一,二是GBK的两字节,既然不转码,过来就正常显示了。
三,四呢是UTF的三字节,现在不转码,三字节过来用GBK怎么能正常显示了。
当然就出现乱码了呀。
在字符集的问题中,抓住关键的地方,就是转码的问题,始终要记得,决定转码的是Oracle客户端和服务段的编码,和客户端系统的是没有关系的,虽然没有关系,只是决定显示的而已。
这里你可以在linux下用UTF8的系统, 做一下测试,你会发现和这里的结果又不一致。但是道理是相同的。
有兴趣,可以自己先分析一下结果,然后再做实验,看你是是不对的,如果分析对了,呵呵呵,我这里讲的就没有白费叻。
#12
呵呵 先回一个
慢慢再看
免得你超过3次连续回帖限制
慢慢再看
免得你超过3次连续回帖限制
#13
自己对字符集方面的知识还是比较匮乏的
老大有没有什么好的文章推荐一份呀?
就比如说各种字符集的编码规则(比如说用2个字节还是3个字节...),他们之间的范围关系(比如说谁是谁的超级,谁是谁的子集),还有他们的转换关系(比如说从A到B可以转,而从B到A转就会出现乱码)
我刚才搜了下没搜到太好的 我再去搜搜看 不过马上就熄灯了 呵呵
老大有没有什么好的文章推荐一份呀?
就比如说各种字符集的编码规则(比如说用2个字节还是3个字节...),他们之间的范围关系(比如说谁是谁的超级,谁是谁的子集),还有他们的转换关系(比如说从A到B可以转,而从B到A转就会出现乱码)
我刚才搜了下没搜到太好的 我再去搜搜看 不过马上就熄灯了 呵呵
#14
啊,我这里解释的还不清楚么。
#15
我觉得自己讲的很清楚了呀,
星期一看我的blog吧。
星期一看我的blog吧。
#16
不错,收藏了
#17
呵呵 你是讲的很清楚了呀
可是这里只涉及到了UTF8和GBK嘛
我的意思就是说还有些其他字符集之间的关系之类的
可是这里只涉及到了UTF8和GBK嘛
我的意思就是说还有些其他字符集之间的关系之类的
#18
呵呵呵,清楚了就好,关注我周一早上的博客文章吧。
#19
恩 好的我会的
好了
结贴
好了
结贴
#20
#1
1.是。
2.两个编码方式长度都不一样。不是乱码倒怪了。
3.总之就是用你os的nls_lang环境变量中的字符集设置值。
2.两个编码方式长度都不一样。不是乱码倒怪了。
3.总之就是用你os的nls_lang环境变量中的字符集设置值。
#2
关注,学习
#3
第二点和第三点能讲得详细点吗
不是说如果ORACLE发现服务器端和客户端的字符集不一致的时候会自动进行转换的么
不是说如果ORACLE发现服务器端和客户端的字符集不一致的时候会自动进行转换的么
#4
是的。但是oracle是怎么发现“服务器端和客户端的字符集不一致”的呢?
就是通过你设置的nls_lang参数中的字符集参数和数据库字符集对比知道的。
你把两者设置成一样,而os实际又没用nls_lang所指的字符集。这时insert数据的字符集就会出问题了。
具体你可以select name,dump(name) from t;看看。
#5
先问个问题哦
注册表里的那些NLS_LANG和我在命令行下set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK有什么关联吗?
如你所说,ORACLE是通过NLS_LANG来判断客户端和数据库字符集是否一致的。那么ORACLE是通过我在命令行里SET的NLS_LANG还是根据注册表中的NLS_LANG呢?二者间存在什么优先级关系吗?
呵呵 不要嫌麻烦哦
注册表里的那些NLS_LANG和我在命令行下set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK有什么关联吗?
如你所说,ORACLE是通过NLS_LANG来判断客户端和数据库字符集是否一致的。那么ORACLE是通过我在命令行里SET的NLS_LANG还是根据注册表中的NLS_LANG呢?二者间存在什么优先级关系吗?
呵呵 不要嫌麻烦哦
#6
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
#7
5L的问题你自己搜搜吧。
给你的那个查询sql你要最好在两种nls_lang下插入相同的数据后,再执行。这样你就会发现在数据库的相同字符集下,相同的插入字符却有完全不同的编码。这就是乱码的原因。
给你的那个查询sql你要最好在两种nls_lang下插入相同的数据后,再执行。这样你就会发现在数据库的相同字符集下,相同的插入字符却有完全不同的编码。这就是乱码的原因。
#8
C:\Documents and Settings\Admin>set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
C:\Documents and Settings\Admin>sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on 星期五 10月 23 16:14:37 2009
Copyright (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 options
SQL> 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行。
好的 谢谢回答~呵呵 我自己再想想
#9
这里很好解释呀
一个一个来
实验一
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
一个一个来
实验一
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
#10
上面是你实验 的结果, 完全是合理的,下面我们来解释一下,为什么有时候select是乱码,有时有时正常的,完全把你都搞糊涂了。
#11
关键是实验二
怎么我用SIMPLIFIED CHINESE_CHINA.ZHS16GBK的时候,看到了乱码,但是存进去却不是乱码。究竟是怎么回事呀。
我们来看 一,二两条记录,根据上面的回答,我们知道一,二进去的时候,没有转码,所以两个字节。 我们现在来显示,由于客户端是SIMPLIFIED CHINESE_CHINA.ZHS16GBK,和服务器不一致,这时候,服务器和客户端知道要转码了。由UTF8致GBK, 很显然,这里转是有错误的,所以一,二是乱码了。
在来看三 四, 三,四是在GBK的情况下进去的,这时候很显然了,不一致要转码,中文转为utf8,三个字节,显示的时候,一样的,不一致,要转码,本来进去就是utf8进去的,转成GBK当然没有问题了,所以也就正常显示了。
在看实验三
为什么我们set nls_lang=AMERICAN_AMERICA.UTF8后,再看刚刚做进去的三 四又乱码叻。
还是字符集的秘密,这是和服务器一致,不会转码,
一,二是GBK的两字节,既然不转码,过来就正常显示了。
三,四呢是UTF的三字节,现在不转码,三字节过来用GBK怎么能正常显示了。
当然就出现乱码了呀。
在字符集的问题中,抓住关键的地方,就是转码的问题,始终要记得,决定转码的是Oracle客户端和服务段的编码,和客户端系统的是没有关系的,虽然没有关系,只是决定显示的而已。
这里你可以在linux下用UTF8的系统, 做一下测试,你会发现和这里的结果又不一致。但是道理是相同的。
有兴趣,可以自己先分析一下结果,然后再做实验,看你是是不对的,如果分析对了,呵呵呵,我这里讲的就没有白费叻。
#12
呵呵 先回一个
慢慢再看
免得你超过3次连续回帖限制
慢慢再看
免得你超过3次连续回帖限制
#13
自己对字符集方面的知识还是比较匮乏的
老大有没有什么好的文章推荐一份呀?
就比如说各种字符集的编码规则(比如说用2个字节还是3个字节...),他们之间的范围关系(比如说谁是谁的超级,谁是谁的子集),还有他们的转换关系(比如说从A到B可以转,而从B到A转就会出现乱码)
我刚才搜了下没搜到太好的 我再去搜搜看 不过马上就熄灯了 呵呵
老大有没有什么好的文章推荐一份呀?
就比如说各种字符集的编码规则(比如说用2个字节还是3个字节...),他们之间的范围关系(比如说谁是谁的超级,谁是谁的子集),还有他们的转换关系(比如说从A到B可以转,而从B到A转就会出现乱码)
我刚才搜了下没搜到太好的 我再去搜搜看 不过马上就熄灯了 呵呵
#14
啊,我这里解释的还不清楚么。
#15
我觉得自己讲的很清楚了呀,
星期一看我的blog吧。
星期一看我的blog吧。
#16
不错,收藏了
#17
呵呵 你是讲的很清楚了呀
可是这里只涉及到了UTF8和GBK嘛
我的意思就是说还有些其他字符集之间的关系之类的
可是这里只涉及到了UTF8和GBK嘛
我的意思就是说还有些其他字符集之间的关系之类的
#18
呵呵呵,清楚了就好,关注我周一早上的博客文章吧。
#19
恩 好的我会的
好了
结贴
好了
结贴