转载:【字符集】“客户终端字符集”、“NLS_LANG”环境变量以及“数据库字符集”

转载:http://blog.itpub.net/519536/viewspace-615345

自从选用了AL32UTF8字符集做为生产数据库字符集之后,就一直奔走于“乱码”与“转码”之间。

在与“乱码”PK良久之后,有了这个小文儿。

如果想要搞清楚Oracle的字符系统,需要紧紧地抓住三个因素:
一.“客户终端字符集”
二.“NLS_LANG”环境变量
三.“数据库字符集”

如果“NLS_LANG”等于“数据库字符集”时,不需要进行任何转换,直接把字符插入数据库
如果“NLS_LANG”不等于“数据库字符集”,则需要进行转换,乱码的根源就在这里

1.“数据库字符集”是AL32UTF8,具体信息如下:
sys@ora10g> col VALUE for a30
sys@ora10g> select * from nls_database_parameters;

PARAMETER                      VALUE
------------------------------ ------------------------------
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               AL32UTF8
NLS_CALENDAR                   GREGORIAN
NLS_DATE_FORMAT                DD-MON-RR
NLS_DATE_LANGUAGE              AMERICAN
NLS_SORT                       BINARY
NLS_TIME_FORMAT                HH.MI.SSXFF AM
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.3.0

20 rows selected.

2.“客户终端字符集”信息如下:
以下实验使用了两种主要客户端(不包括后面提到的PL/SQL Developer和Toad):一个是XP的cmd命令行工具,另一个是PuTTY工具。
1)XP字符集是
C:\>chcp
Active code page: 936
代码页936就是中文字符集GBK,可以参考msdn的资料《Windows Codepage 936》
http://www.microsoft.com/globaldev/reference/dbcs/936.htm

2)PuTTY字符集我的设置:utf8

3.客户端使用AL32UTF8字符集进行测试
C:\>set NLS_LANG=AMERICAN_AMERICA.AL32UTF8

C:\>sqlplus sec/sec@DB_AL32UTF8

SQL*Plus: Release 10.2.0.1.0 - Production on Tue Sep 22 16:12:14 2009

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options

sec@ora10g> drop table t purge;

Table dropped.

sec@ora10g> create table t (x varchar2(20), y varchar2(20));

Table created.

sec@ora10g> insert into t values ('圣','AL32UTF8');

1 row created.

sec@ora10g> commit;

Commit complete.

sec@ora10g> col x for a10
sec@ora10g> col dump(x) for a30
sec@ora10g> select x, y, dump(x) from t;

X          Y                    DUMP(X)
---------- -------------------- ------------------------------
圣          AL32UTF8             Typ=1 Len=2: 202,165

4.客户端使用WE8ISO8859P1字符集进行测试
C:\>set NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1

C:\>sqlplus sec/sec@DB_AL32UTF8

SQL*Plus: Release 10.2.0.1.0 - Production on Tue Sep 22 16:14:55 2009

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options

sec@ora10g> insert into t values ('圣','WE8ISO8859P1');

1 row created.

sec@ora10g> commit;

Commit complete.

sec@ora10g>
sec@ora10g> col x for a10
sec@ora10g> col dump(x) for a30
sec@ora10g> select x, y, dump(x) from t;

X          Y                    DUMP(X)
---------- -------------------- ------------------------------
           AL32UTF8             Typ=1 Len=2: 202,165
圣         WE8ISO8859P1         Typ=1 Len=4: 195,138,194,165

5.客户端使用ZHS16GBK字符集进行测试
C:\>set NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

C:\>sqlplus sec/sec@DB_AL32UTF8

SQL*Plus: Release 10.2.0.1.0 - Production on Tue Sep 22 16:17:13 2009

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options

sec@ora10g> insert into t values ('圣','ZHS16GBK');

1 row created.

sec@ora10g> commit;

Commit complete.

sec@ora10g> col x for a10
sec@ora10g> col dump(x) for a30
sec@ora10g> select x, y, dump(x) from t;

X          Y                    DUMP(X)
---------- -------------------- ------------------------------
?         AL32UTF8             Typ=1 Len=2: 202,165
ꥠ       WE8ISO8859P1         Typ=1 Len=4: 195,138,194,165
圣         ZHS16GBK             Typ=1 Len=3: 229,156,163

6.使用PuTTY以ssh方式连接数据库服务器进行测试
ora10g@secDB /home/oracle$ sqlplus sec/sec

SQL*Plus: Release 10.2.0.3.0 - Production on Tue Sep 22 16:21:17 2009

Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options

sec@ora10g> insert into t values ('圣','PuTTY AL32UTF8');

1 row created.

sec@ora10g> commit;

Commit complete.

sec@ora10g> col x for a10
sec@ora10g> col dump(x) for a30
sec@ora10g> select x, y, dump(x) from t;

X          Y                    DUMP(X)
---------- -------------------- ------------------------------
?          AL32UTF8             Typ=1 Len=2: 202,165
ꥠ        WE8ISO8859P1         Typ=1 Len=4: 195,138,194,165
圣         ZHS16GBK             Typ=1 Len=3: 229,156,163
圣         PuTTY AL32UTF8       Typ=1 Len=3: 229,156,163

7.最后我们将NLS_LANG置空进行一下最后的尝试
C:\>set NLS_LANG=

C:\>sqlplus sec/sec@DB_AL32UTF8

SQL*Plus: Release 10.2.0.1.0 - Production on Tue Sep 22 16:24:57 2009

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options

sec@ora10g>  insert into t values ('圣','unset NLS_LANG');

1 row created.

sec@ora10g> commit;

Commit complete.

sec@ora10g> col x for a10
sec@ora10g> col dump(x) for a30
sec@ora10g> select x, y, dump(x) from t;

X          Y                    DUMP(X)
---------- -------------------- ------------------------------
圣         AL32UTF8             Typ=1 Len=2: 202,165
脢楼       WE8ISO8859P1         Typ=1 Len=4: 195,138,194,165
鍦?        ZHS16GBK             Typ=1 Len=3: 229,156,163
鍦?        PuTTY AL32UTF8       Typ=1 Len=3: 229,156,163
圣         unset NLS_LANG       Typ=1 Len=2: 202,165

8.Toad中“Execute as script”的执行效果:
X          Y                    DUMP(X)
---------- -------------------- ------------------------------
?          AL32UTF8             Typ=1 Len=2: 202,165
ꥠ       WE8ISO8859P1         Typ=1 Len=4: 195,138,194,165
圣         ZHS16GBK             Typ=1 Len=3: 229,156,163
圣         PuTTY AL32UTF8       Typ=1 Len=3: 229,156,163
?          unset NLS_LANG       Typ=1 Len=2: 202,165

5 rows selected.

9.Toad中“F9”的执行效果:
X          Y                    DUMP(X)
---------- -------------------- ------------------------------
圣         AL32UTF8             Typ=1 Len=2: 202,165
脢楼         WE8ISO8859P1         Typ=1 Len=4: 195,138,194,165
鍦         ZHS16GBK             Typ=1 Len=3: 229,156,163
鍦         PuTTY AL32UTF8       Typ=1 Len=3: 229,156,163
圣         unset NLS_LANG       Typ=1 Len=2: 202,165

10.PL/SQL Developer中“Command Window”执行效果
X          Y                    DUMP(X)
---------- -------------------- ------------------------------
?          AL32UTF8             Typ=1 Len=2: 202,165
ꥠ        WE8ISO8859P1         Typ=1 Len=4: 195,138,194,165
圣         ZHS16GBK             Typ=1 Len=3: 229,156,163
圣         PuTTY AL32UTF8       Typ=1 Len=3: 229,156,163
?          unset NLS_LANG       Typ=1 Len=2: 202,165

11.PL/SQL Developer中“F8”执行效果
X          Y                    DUMP(X)
---------- -------------------- ------------------------------
?          AL32UTF8             Typ=1 Len=2: 202,165
ꥠ       WE8ISO8859P1         Typ=1 Len=4: 195,138,194,165
圣         ZHS16GBK             Typ=1 Len=3: 229,156,163
圣         PuTTY AL32UTF8       Typ=1 Len=3: 229,156,163
?          unset NLS_LANG       Typ=1 Len=2: 202,165

12.实验结论
1)如果有可能,尽量保证客户端编码(Windows XP的cmd工具可以使用chcp命令来确认)、NLS_LANG参数和数据库字符集这三个内容一致,这样设置,无论是从性能上,还是从防止编码转换上都是最佳的;
2)如果目的是支持中文,数据库Server端的字符集应该尽量选择ZHS16GBK或AL32UTF8字符集,这样可以减少因不当的“转码”导致的字符乱码故障;
3)(推荐)可已将NLS_LANG参数与操作终端字符编码一致,这样可以保证数据库能正确获得应用终端使用的编码,这时会发生“编码转换”,但是,这样就可以保证正确转码,可以防止错误的编码存入数据库;
4)(不推荐)也可以将NLS_LANG参数与数据库服务器端的编码一致,这样,客户端无论是发送到服务器端还是从服务器接收数据都不会“转码”,这样能保证客户端对字符的显示效果,但是,一定要小心,这时数据库服务器上存放的字符编码很可能是错误的。
5)PL/SQL Developer工具在AL32UTF8字符集下貌似可以保证数据效果,但是“Toad同学”貌似不太“稳定”。

secooler
09.09.22

-- The End --

时间: 2024-10-30 08:49:24

转载:【字符集】“客户终端字符集”、“NLS_LANG”环境变量以及“数据库字符集”的相关文章

oracle 数据库字符集研究 下篇

整理自:http://blog.itpub.net/519536/viewspace-615379/ 自从选用了AL32UTF8字符集做为生产数据库字符集之后,就一直奔走于"乱码"与"转码"之间. 如果想要搞清楚Oracle的字符系统,需要紧紧地抓住三个因素:一."客户终端字符集"二."NLS_LANG"环境变量三."数据库字符集" 如果"NLS_LANG"等于"数据库字符集&

oracle 数据库字符集研究 中篇

四.EXP/IMP 与 字符集 4.1 EXP/IMP    Export 和 Import 是一对读写Oracle数据的工具.Export 将 Oracle 数据库中的数据输出到操作系统文件中, Import 把这些文件中的数据读到Oracle 数据库中,由于使用exp/imp进行数据迁移时,数据从源数据库到目标数据库的过程中有四个环节涉及到字符集,如果这四个环节的字符集不一致,将会发生字符集转换. EXP     ____________ _________________ ________

Linux Shell脚本系列教程(三):变量和环境变量

  这篇文章主要介绍了Linux Shell脚本系列教程(三):变量和环境变量,本文讲解了普通变量.获取字符串的长度.环境变量等内容,需要的朋友可以参考下 一.玩转变量和环境变量 变量是任何一种编程语言都必不可少的组成部分,用于存放各种类型的变量.脚本语言大多是弱类型语言(动态语言),也就是说在使用变量时,不需要事先声明变量的类型,只需要直接赋值就可以.在Bash中,每一个变量的值都是字符串.无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储.有一些特殊的变量会被shell环境和操作系统

java在linux里设置环境变量后,提示没有那个目录?

问题描述 java在linux里设置环境变量后,提示没有那个目录? 我是放在./opt下的,所属人, 所属组也都设置完了, 请大牛.这是怎么回事,在线等 解决方案 root@ubuntu-2:~# cd /opt/java/jdk1.7 root@ubuntu-2:/opt/java/jdk1.7# cd bin root@ubuntu-2:/opt/java/jdk1.7/bin# ls appletviewer jarsigner javap jdb jps jvisualvm rmic t

Linux Shell脚本系列教程(三):变量和环境变量_linux shell

一.玩转变量和环境变量 变量是任何一种编程语言都必不可少的组成部分,用于存放各种类型的变量.脚本语言大多是弱类型语言(动态语言),也就是说在使用变量时,不需要事先声明变量的类型,只需要直接赋值就可以.在Bash中,每一个变量的值都是字符串.无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储.有一些特殊的变量会被shell环境和操作系统保留,用来存储一些特别的值,这类变量就称为环境变量,相信大家对环境变量也并不陌生,因为即使在windows操作系统上,也存在环境变量. 二.普通变量 普通变

oracle 数据库字符集问题谁帮忙解释一下

问题描述 oracle数据库字符集we8iso8859p1,jdbc连接怎样设置和数据库字符集一致?

oracle字符集是ZHS16GBK Linux环境变量zh_CN.G130,存到数据库里是乱码

问题描述 oracle字符集是ZHS16GBK Linux环境变量zh_CN.G130,存到数据库里是乱码 汉字存进数据库里是乱码,但程序在写LOG日志时能够输出正确的中文 在前端和其他系统交互中的数据也是中文没有错误,谁能帮忙解决一下?

各种MySQL客户环境变量程序概述

所有使用mysqlclient客户库与服务器通信的MySQL客户使用下列环境变量: 使用MYSQL_PWD是不安全的.见6.3 与MySQL服务器连接. "mysql"客户使用MYSQL_HISTFILE环境变量中命名的文件来保存命令行历史,历史文件的缺省值是"$HOME/.mysql_history",这里$HOME是HOME环境变量的值. 所有MySQL程序取许多不同的选项,然而,每个MySQL程序提供一个--help选项,你可以使用它得到程序不同选项的完整描述

Oracle数据库字符集问题解析 zz

oracle|数据|数据库|问题 经常看到一些朋友问ORACLE字符集方面的问题,我想以迭代的方式来介绍一下. 第一次迭代:掌握字符集方面的基本概念. 有些朋友可能会认为这是多此一举,但实际上正是由于对相关基本概念把握不清,才导致了诸多问题和疑问.首先是字符集的概念.我们知道,电子计算机最初是用来进行科学计算的(所以叫做"计算机"),但随着技术的发展,还需要计算机进行其它方面的应用处理.这就要求计算机不仅能处理数值,还能处理诸如文字.特殊符号等其它信息,而计算机本身能直接处理的只有数值