咋又乱码了,Oracle的管理员经常会碰到字符乱码的问题,明明看到很的文档里都提到过只要客户端和服务器端的字符集一致。就能解决乱码问题。
可是我这里明明服务器和客户端字符集一致却显示的时候是乱码,客户端和服务器字符集不一致,反而到不显示乱码了。真是越整越糊涂,剪不断,理还乱。
这不,昨天CSDN上的,一个网友在有关字符集的实验中,就碰到这个问题叻,怎么想都想不通,陷入了上面的疑惑之中,只得在CSDN上求助。
我们先一起看看他的问题和相关的实验吧。
实验主要是针对字符集为研究目的来做的。
Oracle数据库服务器的字符集
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
.....................
用一个表来做中文插入和查询的实验
SQL
>
create
table
tt(name
varchar2
(
100
));
当前系统的字符集
C:Documents
and
SettingsAdmin
>
chcp
活动的代码页:
936
这里chcp查询的是window系统的cmd的字符集编码,当前的cmd的编码是GBK
下面就就设置不同的客户端的字符集来进行插入中文的测试叻。
先设置客户端的字符集编码和服务器的一致
C:Documents
and
SettingsAdmin
>
set
nls_lang
=
AMERICAN_AMERICA.UTF8
下面插入数据
(实验一)
SQL>insert
into
tt
values
(
'
一
'
);
1 row created.
SQL>insert
into
tt
values
(
'
二
'
);
1 row created.
SQL> commit;
SQL
>
select
*
from
tt;
NAME
--
--
一
二
这里一切都还正确,服务器和客户端的字符集一致,这里显示没有乱码。
接下来的实验,就开始让人琢磨不透了
(实验二)
现在切换客户端的字符集到GBK的字符集。
C:Documents
and
SettingsAdmin
>
set
nls_lang
=
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
先看看上面的记录对不对
SQL
>
select
*
from
tt;
NAME
--
------------------------------------------------------------------------------
?
??
乱码出现,这时候,我们可能对结果还比较肯定,还可以很理直气壮的,服务器和客户端的字符集不一致,当然就乱码了呀。那么看看下面的吧。
SQL
>
insert
into
tt
values
(
'
三
'
);
已创建
1
行。
SQL
>
insert
into
tt
values
(
'
四
'
);
已创建
1
行。
SQL
>
commit
;
SQL
>
select
*
from
tt;
NAME
--
------------------------------------------------------------------------------
?
??
三
四
奇怪了吧,上面还理直气壮的说过,由于服务器和客户端字符集不一致,应该是乱码的,怎么这后面两个,却不是乱码了。显示的居然还是正确的叻。
呵呵呵,是不是乱了呀。 先不忙着给你解释,让你先继续下面的实验,
客户端再次切换到UTF8的字符集上
(实验三)
C:\Documents
and
Settings\Admin
>
set
nls_lang
=
AMERICAN_AMERICA.UTF8
再来看看上面的结果
SQL
>
select
*
from
tt;
NAME
--
------------------------------------------------------------------------------
一
二
涓
鍥
这三和四又不知道变成什么样子了,反正是没有正确显示出来,究竟是怎么回事呀,这客户端和服务器端是一样的字符集,按道理,应该不乱码的,咋这里又乱码了,上面三,四在不一样的字符集倒没有乱码,倒是把人整迷糊叻。究竟是怎么回事呢?
下面我们来揭开这个谜团吧。
先用dump函数看看我们的存的字符的真面目吧。
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
dump揭露了我们存储的真面目,dump不做详细介绍了。有兴趣的可以去查查文档
这里可以看都是一个中文,一,二存进去只有两个字节,而三,四存进去是3个字节,究竟是怎么回事叻。导致这里的差异的就是字符集的原因。
还记得,一,二是用UTF8的客户端存进去的吧。对于Oracle来说,Oracle认识的客户端字符集,系统的字符集他是不关心
的,当服务器字符集和客户端字符集一致的时候,Oracle在客户端和服务器端交换的时候,不会做字符集的转换,这样,我们输入的中文编码两个字节,原封
不动的交给服务器端,服务器存到数据库里,也就是2个字节叻。后面的三,四的时候,客户端字符集是GBK,和服务器不一致,所以在服务端和客户端交互中,
发生转码,这里客户端的中文编码转换到UTF8,是三个字节,这样三,四存到数据库里都是三个字节叻。
既然是这样,那么用UTF8看到的一,二是正常的,他们存的是GBK编码的字节,而三,四存的是UTF8,和你的客户端一致的字符集,反倒是不
正常的叻。问题还是用上面的的原因来解释,根据dump的信息,我们可以看到,一二,是以GBK存储的,三,四是用UTF8编码存的。当我们select
的时候,数据库找到了一二三四的数据,返回给Oracle客户端,当UTF8时,和数据库字符集一致,这个过程不发生转码,所以这里的字节原封不动的传到
了客户端显示,一,二是GBK编码的2个字节,显示的时候,我们的客户端的系统的cmd是GBK的字符集,也就正常显示了。而三,四叻。传过来的是
UTF8编码的字节,在GBK的cmd环境里,当然就不能正常显示了哟,也就出现了怪异的字符了。
当我们的客户端的字符集为GBK的时候呢。和服务器端的不一致,那么这个过程中服务器到客户端的过程中会进行转码,有UTF8转至到GBK,
而一,二已经是GBK的2个字节了,这个过程肯定不对,所以出现乱码,这也就是实验三的结果。而三,四呢,本身存的就是UTF8编码的三个字节,其实就是
有GBK刚才转成的,现在回过去,当然是可以转变为GBK的编码了。然后cmd是GBK的编码,当然就正常的显示了。
也就出现了实验二的结果。
通过这里的实验,我们的分析的依据就是服务器段和Oracle客户端的字符集的一致的关系,如果不一致,在服务器和Oracle客户端交互的过
程中,将会按两种字符集编码进行转码,反之,如果一致的话,在交互的过程中,不进行编码,字符直接的进行传输。 这就是这里最基本的分析原理了。
安装我们的分析原理,我们一起来猜想一下,我现在是如果客户端换在linux的utf8的操作系统环境中,
现在我们的Oracle的客户端环境的字符集是utf8
[oracle$ oracle]export
nls_lang
=
AMERICAN_AMERICA.UTF8
在这样的sqlplus环境中,我们还是访问上的表
SQL
>
select
name,
dump
(name)
from
tt;
这时候的结果,将如何显示叻?这里的一,二,三,四四条记录,是和我们的实验三(Oracle的客户端也是UTF8的编码)一样的结果嘛?
如果我们在这个Linux的sqlplus的环境中,再次插入五,六两条记录,他们又是怎样的,这个新插入的,五,六两条记录在实验二和实验三的环境里进行查询时,又会出现什么样的情况叻?
最后留下的这两个问题,就是对大家的检验,如果大家可以分析出结果,并能够尝试一下的话,那么大家就不再怕这个剪不断,理还乱的Oracle数据库的字符乱码的问题叻。
有兴趣,并且懂java的朋友,可以用java程序再来访问一下这里的所有数据,看又是什么样的情况?提示,java的thin的连接也是Oracle的客户端,但是不像oci以及其他客户端的程序那样,java不需要指定客户端的字符集。
做实验的过程中有问题的朋友,可以发邮件把你的问题反馈给我,我们一起讨论。
相关推荐
Linux 下的 Oracle 数据库在导入数据库时出现中文乱码问题,这是因为 Oracle 数据库中的字符集格式不支持中文。解决方法是通过修改字符集格式,将其修改成支持中文的格式,这样可以正常显示中文字符。 Oracle ...
### JDBC 连接 Oracle 字符集不同导致乱码问题解析及解决方案 #### 问题背景 在使用 JDBC(Java Database Connectivity)连接 Oracle 数据库时,可能会遇到一个常见的问题:从远程 Oracle 数据库获取的数据出现乱码...
本文将深入探讨Oracle数据库字符集的概念、重要性、修改过程及其潜在问题,特别是当尝试修改数据库字符集时遇到的乱码问题。 ### Oracle数据库字符集概述 Oracle数据库字符集是指用于表示数据库中所有字符数据的...
由于历史的原因,早期的oracle没有中文字符集(如oracle6、oracle7、oracle7.1),但有的用户从那时起就使用数据库了, 并用US7ASCII字符集存储了中文,或是有的用户在创建数据库时,不考虑清楚,随意选择一个默认的...
### Oracle 修改字符集 在Oracle数据库管理中,有时我们需要更改数据库的字符集以适应不同的语言环境或解决数据兼容性问题。...这不仅可以提高数据库的兼容性和性能,还可以帮助解决由字符集不匹配引起的各种问题。
Oracle字符集是数据库管理系统Oracle中的一个重要概念,它决定了数据库如何存储和处理文本数据。字符集不仅影响着数据的准确性和一致性,还与全球化应用、数据迁移和数据交换密切相关。本篇将深入探讨Oracle字符集的...
### Oracle字符集的查看与客户端字符集的修改 #### 一、Oracle字符集的基本概念 在Oracle数据库系统中,字符集(charset)是用于表示文本数据的编码方式。正确设置和管理字符集对于确保数据的一致性和正确性至关重要...
oracle修改字符集,解决乱码问题.
"Oracle字符集(4).txt"可能涵盖字符集问题的诊断和修复,如如何识别和处理乱码问题,以及如何通过ALTER DATABASE命令更改数据库字符集。 最后,"Oracle字符集(5).txt"可能涉及数据导入导出与字符集的关联,如...
### Oracle字符集问题详解 #### 一、问题背景 在使用Oracle数据库的过程中,经常会遇到字符集不一致导致的各种问题。特别是在使用PL/SQL Developer等工具连接数据库时,如果数据库字符集(Database Character Set...
Oracle数据库字符集问题解析
本文将详细介绍如何通过Oracle提供的工具进行字符集转换,避免因字符集问题导致的数据丢失或显示异常。 #### 二、字符集转换背景 假设当前数据库字符集为WE8ISO8859P1,但实际需求要求其字符集为AL32UTF8。面对...
Oracle 数据库字符集问题解决方案大全 Oracle 数据库字符集问题解决方案大全中,提出了 Oracle 数据库汉字显示异常的解决方案。该文档涵盖了字符集的概念、字符集的设置、字符集的影响因素、解决汉字显示异常的...
在处理"Oracle英文字符集转中文"的问题时,理解字符集原理,熟练运用各种转换工具和技巧,是解决问题的关键。 总之,跨字符集的数据操作是一项复杂但必要的任务,尤其是在全球化应用中。通过深入理解字符集的工作...
本文将深入探讨Oracle字符集的相关概念,包括如何通过设置环境变量来修改客户端字符集,以此解决因字符集差异而导致的数据转换或损耗问题。 #### Oracle字符集的重要性 Oracle数据库通过字符集支持多种语言环境下...
本文还介绍了 Oracle 数据库字符集问题的解决方法,包括使用 exp/imp 工具来转换数据库字符集,使用 Unicode 字符集来存储数据等。 Oracle 数据库字符集问题解析对 Oracle 数据库管理系统的应用和发展产生了深远的...
### Oracle字符集的查看与修改详解 #### 一、Oracle字符集概述 Oracle数据库系统支持多种字符集,以便处理各种语言和地区的信息。字符集的选择对于数据的存储和处理至关重要,尤其是在全球化环境中,需要处理多种...
### Oracle中文字符集问题解析与解决方案 在Oracle数据库的日常管理和应用开发中,中文字符集的设置和管理是一项至关重要的工作。不当的字符集配置可能导致数据存储错误、查询结果异常或用户界面显示乱码等问题。...
2. **操作系统字符集设置问题**:如果操作系统的默认字符集与数据库的字符集设置不一致,也会导致乱码的出现。 3. **应用程序编码问题**:部分应用程序在处理字符串时,如果没有正确地指定字符集,也可能导致乱码。 ...