oracle 数据库字符集研究 下篇

本文涉及的产品
云原生数据仓库AnalyticDB MySQL版,基础版 8ACU 100GB 1个月
简介: 整理自:http://blog.itpub.net/519536/viewspace-615379/自从选用了AL32UTF8字符集做为生产数据库字符集之后,就一直奔走于“乱码”与“转码”之间。

整理自:http://blog.itpub.net/519536/viewspace-615379/

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

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

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


1.“数据库字符集”是AL32UTF8,具体信息如下:
SQL> col VALUE for a30
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       AL32UTF8
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       AL16UTF16
NLS_RDBMS_VERSION       11.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  Linux环境(export NLS_LANG=AMERICAN_AMERICA.AL32UTF8)
[oracle@lyg ~]$ export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
[oracle@lyg ~]$ echo $LANG
en_US.UTF-8
[oracle@lyg ~]$ echo $NLS_LANG
AMERICAN_AMERICA.AL32UTF8

[oracle@lyg ~]$ sqlplus "/as sysdba"
SQL*Plus: Release 11.2.0.3.0 Production on Thu Oct 30 14:11:16 2014
Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> drop table t purge;
drop table t purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist
SQL>  create table t (x varchar2(20), y varchar2(20));
Table created.
SQL> insert into t values ('圣','AL32UTF8');
1 row created.
SQL> commit;
Commit complete.

SQL> col x for a10
SQL> col dump(x) for a30
SQL> select x, y, dump(x) from t;

X   Y DUMP(X)
---------- -------------------- ------------------------------
圣         AL32UTF8             Typ=1 Len=3: 229,156,163


4.客户端使用WE8ISO8859P1字符集进行测试
C:\>set NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1    Linux环境(export NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1
[oracle@lyg ~]$ export NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1
[oracle@lyg ~]$ echo $NLS_LANG
AMERICAN_AMERICA.WE8ISO8859P1
[oracle@lyg ~]$ sqlplus "/as sysdba"
SQL*Plus: Release 11.2.0.3.0 Production on Thu Oct 30 14:15:48 2014
Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> insert into t values ('圣','WE8ISO8859P1');
1 row created.
SQL> commit;
Commit complete.

SQL> col x for a10
SQL> col dump(x) for a30
SQL> select x, y, dump(x) from t;
X   Y DUMP(X)
---------- -------------------- ------------------------------
¿   AL32UTF8 Typ=1 Len=3: 229,156,163
  WE8ISO8859P1 Typ=1 Len=6: 195,165,194,156,194,163

5.客户端使用ZHS16GBK字符集进行测试
C:\>set NLS_LANG=AMERICAN_AMERICA.ZHS16GBK     Linux环境(export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
[oracle@lyg ~]$ echo $LANG
en_US.UTF-8
[oracle@lyg ~]$ echo $NLS_LANG
AMERICAN_AMERICA.ZHS16GBK
[oracle@lyg ~]$ sqlplus "/as sysdba"
SQL*Plus: Release 11.2.0.3.0 Production on Thu Oct 30 14:21:02 2014
Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options


SQL> insert into t values ('圣','ZHS16GBK');
ERROR:
ORA-01756: quoted string not properly terminated       ——11.2.0.3的环境,插不进去,网上查了下,应该是字符集设置的问题。

SQL> insert into t values ('A','ZHS16GBK');        ——尝试插了个A,是可以的。
1 row created.

又尝试插入了一个汉字“一”,倒是可以,但是插入“二”就又不行了。

SQL> select x, y, dump(x) from t;

X   Y DUMP(X)
---------- -------------------- ------------------------------
ʥ   AL32UTF8 Typ=1 Len=3: 229,156,163
£¿£¿¡   WE8ISO8859P1 Typ=1 Len=6: 195,165,194,156,194,163
A   ZHS16GBK Typ=1 Len=1: 65
  ZHS16GBK Typ=1 Len=6: 230,182,147,226,130,172

下面这是原作者10g中的测试:
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.我把xshell设置长GB2312/16GB分别以ssh方式连接数据库服务器进行测试

SQL> insert into t values ('圣','xshgb2312 AL32UTF8');
1 row created.

SQL> commit;
Commit complete.

SQL> select x, y, dump(x) from t;
X   Y DUMP(X)
---------- -------------------- ------------------------------
?   AL32UTF8 Typ=1 Len=3: 229,156,163
??#   WE8ISO8859P1 Typ=1 Len=6: 195,165,194,156,194,163
A   ZHS16GBK Typ=1 Len=1: 65
??   ZHS16GBK Typ=1 Len=6: 230,182,147,226,130,172
??   xshgb2312 AL32UTF8 Typ=1 Len=6: 239,191,189,239,191,189

接下来,我再换成16GBK试试:


SQL> insert into t values ('圣','xsh GBK');
1 row created.


SQL> commit;
Commit complete.

SQL> col x for a10
SQL> col dump(x) for a30
SQL> select x, y, dump(x) from t;

X   Y                                 DUMP(X)
---------- --------------------                ------------------------------
?   AL32UTF8                  Typ=1 Len=3: 229,156,163
??#   WE8ISO8859P1          Typ=1 Len=6: 195,165,194,156,194,163
A   ZHS16GBK           Typ=1 Len=1: 65
??   ZHS16GBK           Typ=1 Len=6: 230,182,147,226,130,172
??   xshgb2312 AL32UTF8  Typ=1 Len=6: 239,191,189,239,191,189
??   xsh GBK Typ=1      Len=6: 239,191,189,239,191,189

6 rows selected.



7.最后我们将NLS_LANG置空进行一下最后的尝试
C:\>set NLS_LANG=        Linux环境(export NLS_LANG= 
 [oracle@lyg ~]$ export NLS_LANG= 
[oracle@lyg ~]$ echo $NLS_LANG
[oracle@lyg ~]$ sqlplus "/as sysdba"
SQL*Plus: Release 11.2.0.3.0 Production on Thu Oct 30 14:52:00 2014
Copyright (c) 1982, 2011, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options


SQL> insert into t values ('圣','unset NLS_LANG');
1 row created.

SQL> commit;
Commit complete.

SQL> col x for a10
SQL> col dump(x) for a30
SQL> select x, y, dump(x) from t;
X   Y DUMP(X)
---------- -------------------- ------------------------------
?   AL32UTF8 Typ=1 Len=3: 229,156,163
??#   WE8ISO8859P1 Typ=1 Len=6: 195,165,194,156,194,163
A   ZHS16GBK Typ=1 Len=1: 65
??   ZHS16GBK Typ=1 Len=6: 230,182,147,226,130,172
??   xshgb2312 AL32UTF8 Typ=1 Len=6: 239,191,189,239,191,189
??   xsh GBK Typ=1 Len=6: 239,191,189,239,191,189
???   unset NLS_LANG Typ=1 Len=9: 239,191,189,239,191,189,239,191,189

7 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”执行效果(我plsql dev设置的字符集是16GBK的(因为我的windows系统环境变量的设置))


11.PL/SQL Developer中“F8”执行效果(我plsql dev设置的字符集是16GBK的(因为我的windows系统环境变量的设置))



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



相关实践学习
AnalyticDB MySQL海量数据秒级分析体验
快速上手AnalyticDB MySQL,玩转SQL开发等功能!本教程介绍如何在AnalyticDB MySQL中,一键加载内置数据集,并基于自动生成的查询脚本,运行复杂查询语句,秒级生成查询结果。
阿里云云原生数据仓库AnalyticDB MySQL版 使用教程
云原生数据仓库AnalyticDB MySQL版是一种支持高并发低延时查询的新一代云原生数据仓库,高度兼容MySQL协议以及SQL:92、SQL:99、SQL:2003标准,可以对海量数据进行即时的多维分析透视和业务探索,快速构建企业云上数据仓库。 了解产品 https://www.aliyun.com/product/ApsaraDB/ads
相关文章
|
18天前
|
Oracle 关系型数据库 数据库
数据库数据恢复—Oracle数据库文件出现坏块的数据恢复案例
打开oracle数据库报错“system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。 数据库没有备份,无法通过备份去恢复数据库。用户方联系北亚企安数据恢复中心并提供Oracle_Home目录中的所有文件,急需恢复zxfg用户下的数据。 出现“system01.dbf需要更多的恢复来保持一致性”这个报错的原因可能是控制文件损坏、数据文件损坏,数据文件与控制文件的SCN不一致等。数据库恢复工程师对数据库文件进一步检测、分析后,发现sysaux01.dbf文件损坏,有坏块。 修复并启动数据库后仍然有许多查询报错,export和data pump工具使用报错。从数据库层面无法修复数据库。
数据库数据恢复—Oracle数据库文件出现坏块的数据恢复案例
|
6天前
|
Oracle 关系型数据库 数据库
Oracle数据恢复—异常断电导致Oracle数据库数据丢失的数据恢复案例
Oracle数据库故障: 机房异常断电后,Oracle数据库启库报错:“system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。数据库没有备份,归档日志不连续。用户方提供了Oracle数据库的在线文件,需要恢复zxfg用户的数据。 Oracle数据库恢复方案: 检测数据库故障;尝试挂起并修复数据库;解析数据文件。
|
5天前
|
Oracle NoSQL 关系型数据库
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
17 2
|
7天前
|
SQL 安全 Java
探索研究Servlet 数据库访问
【9月更文挑战第28天】
17 0
|
9天前
|
SQL Oracle 关系型数据库
Oracle数据库管理:从入门到精通
表(Table):表是Oracle数据库中存储数据的基本结构单元,由行(Row)和列(Column)组成。每行代表一个记录,每列代表一个字段。 SQL(Structured Query Language):SQL是Oracle数据库的核心语言,用于与数据库交互,执行查询、插入、更新和删除等操作。 数据库实例与数据库:在Oracle中,数据库实例是一组后台进程和内存结构,用于管理数据库并提供服务。而数据库则是数据的物理存储,包括数据文件、控制文件、联机日志和参数文件等。
31 0
|
2月前
|
监控 Oracle 关系型数据库
"深度剖析:Oracle SGA大小调整策略——从组件解析到动态优化,打造高效数据库性能"
【8月更文挑战第9天】在Oracle数据库性能优化中,系统全局区(SGA)的大小调整至关重要。SGA作为一组共享内存区域,直接影响数据库处理能力和响应速度。本文通过问答形式介绍SGA调整策略:包括SGA的组成(如数据缓冲区、共享池等),如何根据负载与物理内存确定初始大小,手动调整SGA的方法(如使用`ALTER SYSTEM`命令),以及利用自动内存管理(AMM)特性实现智能调整。调整过程中需注意监控与测试,确保稳定性和性能。
164 2
|
3月前
|
存储 缓存 Oracle
Oracle数据库可扩展性和性能
【7月更文挑战第6天】
72 7
|
存储 SQL 负载均衡
达梦数据库与Oracle数据库:功能、性能和适用场景对比
数据库在现代信息技术领域中扮演着至关重要的角色。在企业级应用中,选择正确的数据库管理系统对于数据存储、处理和查询效率至关重要。本文将对比两个备受关注的数据库管理系统——达梦数据库和Oracle数据库,从功能、性能和适用场景等方面进行深入探讨,以帮助读者在选择合适数据库时做出明智的决策。
2721 1
|
SQL Oracle 安全
Oracle优化01-引起数据库性能问题的因素
Oracle优化01-引起数据库性能问题的因素
156 0

热门文章

最新文章

推荐镜像

更多
下一篇
无影云桌面