热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Oracle字符集详解:图表解析与中文乱码解决方案

本文详细解析了Oracle数据库中的字符集机制,通过图表展示了不同字符集之间的转换过程,并针对中文乱码问题提供了有效的解决方案。文章深入探讨了字符集配置、数据迁移和兼容性问题,为数据库管理员和开发人员提供了实用的参考和指导。

经常碰到SQLPLUS展现乱码的问题,字符集和相关的定义都有说明但是很少有能把这些关系说的很简单易懂的。

在此之前我们需要搞清楚三个概念,操作系统字符集,客户端字符集,Oracle字符集:

操作系统字符集:对应的参数是LANG,这个参数应该是Oracle数据库的超集,如果操作系统不支持,那么我们的数据就会乱码。这里的操作系统指的是客户端的操作系统。服务器端的操作系统不会影响数据的存取。

数据库字符集:NLS_CHARACTERSET,可以在nls_database_parameters中查看当前数据库的字符集,安装数据库的时候选择,一般不修改,不过在新的字符集是现有字符集的严格超集的情况下可以改,其他情况下修改可能导致数据库异常。例如将UTF8字符集修改为AL32UTF8

关于子集超集的映射关系,见如下Oracle官网的文档的Binary Subset-Superset Pairs

http://docs.oracle.com/database/121/NLSPG/applocaledata.htm#NLSPG591 

客户端字符集:对应的参数是NLS_LANG,如果客户端未设置,此时则取的是安装时数据库的默认参数

为了帮助理解,我画了一张图如下,图中标红部分如果一致表示数据的存储方式一致,即如果LANG、NLS_LANG、NLS_CHARACTERSET的编码是一致的如UTF8,那么数据的传输过程中不会异常,字符乱码只是显示问题。

#Oracle字符集的简单图解,中文乱码解决

1、操作系统字符集

Linux下首先locale 查看字符集

[oracle@oddpc ~]$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MOnETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHOnE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
[oracle@oddpc ~]$ echo $LANG
en_US.UTF-8


2、该主机并未安装中文支持包,设置LANG后可以效果如下,显然无路如何调整NLS_LANG在这台机器上都无法展现中文

[oracle@evenpc ~]$ export LANG=zh_CN.utf8
[oracle@evenpc ~]$ date
2016? 10? 13? ??? 15:17:01 CST


3、安装中文支持包,使用yum -y groupinstall chinese-support 可以安装中文支持包,安装过程略过,安装完毕后可以正常显示中文

[oracle@oddpc ~]$ export LANG=zh_CN.utf8
[oracle@oddpc ~]$ date
2016年 10月 13日 星期四 15:14:19 CST

4、接下来就是展现测试,我安装了两个数据库实例PROD1和PROD5,PROD1 的字符集是WE8MSWIN1252,PROD5的字符集是AL32UTF8

默认情况下NLS_LANG是空的,此时NLS_LANG取默认安装时的值,PROD1是AMRICAN,PROD5是SIMPLIFIED CHINESE

[oracle@oddpc ~]$ echo $NLS_LANG
[oracle@oddpc ~]$ 
SQL> show parameter lang        

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
nls_date_language                    string
nls_language                         string      AMERICAN
SQL> select sysdate from dual;

SYSDATE
---------
13-OCT-16
 

PROD5

SQL> show parameter lang  

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
nls_date_language                    string
nls_language                         string      SIMPLIFIED CHINESE
SQL> select sysdate from dual;

SYSDATE
----------
13-10?-16

5、PROD5 发生乱码,PROD1英文正常,设置下NLS_LANG参数

PROD1 的结果如下,可以看到提示信息已经变成中文,但是由于字符集非UTF8中文字符存入后将乱码

[oracle@oddpc ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.UTF8"
[oracle@oddpc ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on 星期四 10月 13 15:42:46 2016

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


连接到: 
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> show parameter lang

NAME                                 TYPE                              VALUE
------------------------------------ --------------------------------- ------------------------------
nls_date_language                    string                            SIMPLIFIED CHINESE
nls_language                         string                            SIMPLIFIED CHINESE
SQL> show parameter db_name

NAME                                 TYPE                              VALUE
------------------------------------ --------------------------------- ------------------------------
db_name                              string                            PROD1
SQL> show parameter lang

NAME                                 TYPE                              VALUE
------------------------------------ --------------------------------- ------------------------------
nls_date_language                    string                            SIMPLIFIED CHINESE
nls_language                         string                            SIMPLIFIED CHINESE
SQL> select sysdate from dual;

SYSDATE
------------
13-10? -16
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                         WE8MSWIN1252
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行。
 
 

PROD5的结果如下,此时PROD5显示正常

[oracle@oddpc ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.UTF8"
[oracle@oddpc ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.3.0 Production on 星期四 10月 13 15:46:36 2016

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


连接到: 
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> show parameter db_name

NAME                                 TYPE                              VALUE
------------------------------------ --------------------------------- ------------------------------
db_name                              string                            PROD5
SQL> select sysdate from dual;

SYSDATE
------------
13-10月-16

SQL> show parameter lang

NAME                                 TYPE                              VALUE
------------------------------------ --------------------------------- ------------------------------
nls_date_language                    string                            SIMPLIFIED CHINESE
nls_language                         string                            SIMPLIFIED CHINESE
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行。
 


总结:通过以上的实验可以看出,客户端展现是否乱码是由NLS_LANG决定,发生中文乱码的情况下,首先查看数据库的NLS_CHARACTERSET是否支持中文存储,如果不支持,无论如何设置均无法正常显示中文。Oracle官方文档上给出了各种语言的编码支持如下。



http://docs.oracle.com/database/121/NLSPG/applocaledata.htm#NLSPG593

Table A-13 Languages and Character Sets Supported by LCSSCAN and GDK

LanguageCharacter Sets

Arabic

AL16UTF16, AL32UTF8, AR8ISO8859P6, AR8MSWIN1256, UTF8

Bulgarian

AL16UTF16, AL32UTF8, CL8ISO8859P5, CL8MSWIN1251, UTF8

Catalan

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Croatian

AL16UTF16, AL32UTF8, EE8ISO8859P2, EE8MSWIN1250, UTF8

Czech

AL16UTF16, AL32UTF8, EE8ISO8859P2, EE8MSWIN1250, UTF8

Danish

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Dutch

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

English

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Estonian

AL16UTF16, AL32UTF8, NEE8IOS8859P4, UTF8

Finnish

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

French

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

German

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Greek

AL16UTF16, AL32UTF8, EL8ISO8859P7, EL8MSWIN1253, UTF8

Hebrew

AL16UTF16, AL32UTF8, IW8ISO8859P8, IW8MSWIN1255, UTF8

Hindi

AL16UTF16, AL32UTF8, IN8ISCII, UTF8

Hungarian

AL16UTF16, AL32UTF8, EE8ISO8859P2, EE8MSWIN1250, UTF8

Indonesian

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Italian

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Japanese

AL16UTF16, AL32UTF8, ISO2022-JP, JA16EUC, JA16SJIS, UTF8

Korean

AL16UTF16, AL32UTF8, ISO2022-KR, KO16KSC5601, KO16MSWIN949, UTF8

Latvian

AL16UTF16, AL32UTF8, NEE8ISO8859P4, UTF8

Lithuanian

AL16UTF16, AL32UTF8, NEE8ISO8859P4, UTF8

Malay

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Norwegian

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Persian

AL16UTF16, AL32UTF8, AR8MSWIN1256, UTF8

Polish

AL16UTF16, AL32UTF8, EE8ISO8859P2, EE8MSWIN1250, UTF8

Portuguese

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Romanian

AL16UTF16, AL32UTF8, EE8ISO8859P2, EE8MSWIN1250, UTF8

Russian

AL16UTF16, AL32UTF8, CL8ISO8859P5, CL8KOI8R, CL8MSWIN1251, RU8PC866, UTF8

Serbian

AL16UTF16, AL32UTF8, CL8ISO8859P5, CL8MSWIN1251, UTF8

Simplified Chinese

AL16UTF16, AL32UTF8, HZ-GB-2312, UTF8, ZHS16GBK, ZHS16CGB231280

Slovak

AL16UTF16, AL32UTF8, EE8ISO8859P2, EE8MSWIN1250, UTF8

Slovenian

AL16UTF16, AL32UTF8, EE8ISO8859P2, EE8MSWIN1250, UTF8

Spanish

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Swedish

AL16UTF16, AL32UTF8, US7ASCII, UTF8, WE8ISO8859P1, WE8ISO8859P15, WE8MSWIN1252

Thai

AL16UTF16, AL32UTF8, TH8TISASCII, UTF8

Traditional Chinese

AL16UTF16, AL32UTF8, UTF8, ZHT16MSWIN950

Turkish

AL16UTF16, AL32UTF8, TR8MSWIN1254, UTF8, WE8ISO8859P9

Ukranian

AL16UTF16, AL32UTF8, CL8ISO8859P5, CL8MSWIN1251, UTF8

Vietnamese

AL16UTF16, AL32UTF8, VN8VN3, UTF8


推荐阅读
  • 本文探讨了MariaDB在当前数据库市场中的地位和挑战,分析其可能面临的困境,并提出了对未来发展的几点看法。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 本文介绍了数据库体系的基础知识,涵盖关系型数据库(如MySQL)和非关系型数据库(如MongoDB)的基本操作及高级功能。通过三个阶段的学习路径——基础、优化和部署,帮助读者全面掌握数据库的使用和管理。 ... [详细]
  • 迎接云数据库新时代:程序员如何应对变革?
    在数据无处不在的时代,数据库成为了管理和处理数据的核心工具。从早期的信息记录方式到现代的云数据库,数据库技术经历了巨大的变革。本文将探讨云数据库的特点及其对程序员的影响。 ... [详细]
  • 2023 ARM嵌入式系统全国技术巡讲旨在分享ARM公司在半导体知识产权(IP)领域的最新进展。作为全球领先的IP提供商,ARM在嵌入式处理器市场占据主导地位,其产品广泛应用于90%以上的嵌入式设备中。此次巡讲将邀请来自ARM、飞思卡尔以及华清远见教育集团的行业专家,共同探讨当前嵌入式系统的前沿技术和应用。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • 深入理解Tornado模板系统
    本文详细介绍了Tornado框架中模板系统的使用方法。Tornado自带的轻量级、高效且灵活的模板语言位于tornado.template模块,支持嵌入Python代码片段,帮助开发者快速构建动态网页。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • ElasticSearch 集群监控与优化
    本文详细介绍了如何有效地监控 ElasticSearch 集群,涵盖了关键性能指标、集群健康状况、统计信息以及内存和垃圾回收的监控方法。 ... [详细]
author-avatar
剡亚军_191
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有