千家信息网

oracle数据库字符集

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,我用的数据库是oracle11.2.0.4,数据库字符集是al32utf8。客户端就是同一台机器的windows 7用window7的客户端连接查看windows客户端中文字符虚拟机 192.168.
千家信息网最后更新 2026年11月02日oracle数据库字符集

我用的数据库是oracle11.2.0.4,数据库字符集是al32utf8。

客户端就是同一台机器的windows 7

用window7的客户端连接

查看windows客户端中文字符



虚拟机 192.168.10.5 数据库是test1 数据库字符集是al32utf8。


C:\Users\Administrator>echo %NLS_LANG% -------查看客户端字符命令

SIMPLIFIED CHINESE_CHINA.AL32UTF8


set NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK -----设置客户端字符命令



数据库是test1 ,数据库字符集是al32utf8。



--session 1 设置客户端字符集为 zhs16gbk(修改注册表nls_lang项的characterset 为zhs16gbk) 向表中插入两个中文字符。



C:\Users\Administrator>echo %NLS_LANG%

SIMPLIFIED CHINESE_CHINA.ZHS16GBK


C:\Users\Administrator>sqlplus sys/oracle@test1 as sysdba;


SQL> create table test(col1 number(1),col2 varchar2(10));

SQL> insert into test values(1,'中国'); --1为session 1的标记

1 row created.

SQL> commit;

Commit complete.

SQL> create table test(col1 number(1),col2 varchar2(10));


表已创建。


SQL> insert into test values(1,'中国');


已创建 1 行。


SQL>

-session 2 设置客户端字符集 al32utf8(修改注册表nls_lang项的characterset 为al32utf8),与数据库字符集相同。 向表中插入两个和session 1相同的中文字符。

C:\Users\Administrator>echo %NLS_LANG%

SIMPLIFIED CHINESE_CHINA.AL32UTF8


C:\Users\Administrator>sqlplus sys/oracle@test1 as sysdba;


SQL*Plus: Release 11.2.0.1.0 Production on 鏄熸湡涓 11鏈?28 10:35:33 2016


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



杩炴帴鍒?

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options


SQL>





SQL> insert into test values(2,'中国'); --2为session 2的标记

1 row created.

SQL> commit;

Commit complete.


--session 1


SQL> select * from test;


COL1 COL2

---------- --------------------

1 中国

2 ???

--session 2

SQL> select * from test;


COL1 COL2

---------- ----------

1 涓浗

2 中国


SQL>

从session 1和session 2的结果中可以看到,相同的字符(注意,我指的是我们看到的,显示为相同的字符 中国),在不同的字符集输入环境(客户端环境变量)下,显示成了乱码。

在zhs16gbk字符集的客户端,我们看到了utf8字符集客户端输入的相同的中文变成了乱码-->col1=2的col2字段

SQL> select * from test;


COL1 COL2

---------- --------------------

1 中国

2 ???

在utf8字符集客户端,我们看到zhs16gbk字符集的客户端输入的中文变成了另外的字符 -->col1=1的col2字段

SQL> select * from test;


COL1 COL2

---------- ----------

1 涓浗 -----三个字符

2 中国

SQL> select col1,dump(col2,1016) from test;


COL1

----------

DUMP(COL2,1016)

-------------------------------------------------------------


1

Typ=1 Len=6 CharacterSet=AL32UTF8: e4,b8,ad,e5,9b,bd


2

Typ=1 Len=4 CharacterSet=AL32UTF8: d6,d0,b9,fa



不同的客户端输入的中文字符,在数据库中存储的字符编码不一致。



session 1 输入的字符"中国" 在数据库中存储的字符编码为"e4,b8,ad,e5,9b,bd".

session 2 输入的字符"中国" 在数据库中存储的字符编码为"d6,d0,b9,fa".


会话一、

中国-------e4,b8,ad,e5,9b,bd 数据库发现客户端16gbk跟数据库端的utf8字符不一致 做了字符转换 首先将客户端 中国 16gbk的(双字节)编码转成utf8(三字节编码) 然后存储下来。


会话二、

中国-------d6,d0,b9,fa 数据库发现客户端utf8跟数据库端的utf8字符一致 欺骗了数据库端,不做字符转换,直接以16gbk(双字节)的字符编码存储到数据库(utf8数据库编码为三字节)中。



session 1 输入的字符"中国" 在数据库中存储的字符编码为"e4,b8,ad,e5,9b,bd"

session 2 输入的字符"中国" 在数据库中存储的字符编码为"d6,d0,b9,fa"



数据库看到客户端的字符集和数据库的字符集一致,此时oracle将不会再对字符作转换,因为它认为两边的字符编码是一致的。而此时,

我们欺骗了数据库,尽管我们将客户端字符集设置为和数据库一致,但是其实我们使用的是zhs16gbk字符集编码(因为此时windows使用的就是这个字符编码),

对于字符"中国",zhs16gbk字符集里对应的编码为d6,d0,b9,fa。此时,oracle不加理会的直接将这个编码保存到了数据库中。




客户端的字符集的作用就是告知数据库端传输的字符编码,跟数据库端的字符集一致就直接存储,不一致就字符转换。




查询是存储的字符转换的逆过程。

session1查询

SQL> select * from test;


COL1 COL2

---------- --------------------

1 中国

2 ???



当session 1开始查询时,oracle从表中取出这两个字符,并按照字符集al32utf8和字符集zhs16gbk的编码映射表,将它的转换成zhs16gbk字符编码,对于编码"e4,b8,ad,e5,9b,bd",

它对应的zhs16gbk的字符编码为"d6,d0,b9,fa",这个编码对应的字符为"中国",所以我们看到了这个字符正常显示出来了,

而对于字符集存储的al32utf8字符编码"d6,d0,b9,fa",

由于我们用于显示字符的windows环境使用的是zhs16gbk字符集,而在zhs16gbk字符集里面并没有对应这个编码的字符或者属于无法显示的符号,utf8---16gbk 转换找不到

于是使用了"?"这样的字符来替换,这就是为什么我们看到session 2输入的字符变成了这样的乱码。






session2查询

SQL> select * from test;


COL1 COL2

---------- ----------

1 涓浗

2 中国

SQL>



当session 2开始查询时,oracle从表中取出这两个字符,由于客户端(nls_lang)和数据库的字符集设置一致,oracle将忽略字符的转换问题,

于是直接将数据库中存储的字符返回给客户端。对于编码为"d6,d0,b9,fa"的字符,返回给客户端,而客户端显示所用的字符集正好是zhs16gbk,在这个字符集里,########(虽然客户端变成ut8,但是转换回来还是以16gbk的,windows依然是16gbk。)

这个编码对应的是"中国"两个字符,所以就正常显示出来了。

对于字符编码"e4,b8,ad,e5,9b,bd",返回到客户端後,因为在zhs16gbk里采用的是双字节存储字符方式,(虽然客户端变成utf8,但是转换回来还是以16gbk的,windows依然是16gbk。)

所以这6字节对应了zhs16gbk字符集的3个字符,也就是我们看到的"涓浗"。






导入导出 exp imp 客户端对字符的影响实验


创建两个库

test1 源数据库 字符集----------- SIMPLIFIED CHINESE_CHINA.AL32UTF8


test2 目标数据库 字符集----------- SIMPLIFIED CHINESE_CHINA.16gbk


创建用户jiang/oracle 建立test表




oracle@linux5:/oracle>export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK" ###########环境变量


SQL> select col1,dump(col2,1016) from test;


COL1

----------

DUMP(COL2,1016)

--------------------------------------------------------------------------------

2

Typ=1 Len=4 CharacterSet=AL32UTF8: d6,d0,b9,fa


1

Typ=1 Len=6 CharacterSet=AL32UTF8: e4,b8,ad,e5,9b,bd




Export: Release 11.2.0.4.0 - Production on 星期一 11月 28 17:05:50 2016


Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.



连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集

服务器使用 AL32UTF8 字符集 (可能的字符集转换)

. 正在导出 pre-schema 过程对象和操作

. 正在导出用户 JIANG 的外部函数库名

. 导出 PUBLIC 类型同义词

. 正在导出专用类型同义词

. 正在导出用户 JIANG 的对象类型定义

即将导出 JIANG 的对象...

. 正在导出数据库链接

. 正在导出序号

. 正在导出簇定义

. 即将导出 JIANG 的表通过常规路径...

. . 正在导出表 TEST导出了 2 行

. 正在导出同义词

. 正在导出视图

. 正在导出存储过程

. 正在导出运算符

. 正在导出引用完整性约束条件

. 正在导出触发器

. 正在导出索引类型

. 正在导出位图, 功能性索引和可扩展索引

. 正在导出后期表活动

. 正在导出实体化视图

. 正在导出快照日志

. 正在导出作业队列

. 正在导出刷新组和子组

. 正在导出维

. 正在导出 post-schema 过程对象和操作

. 正在导出统计信息

成功终止导出, 没有出现警告。







导入到test2 ,目标数据库字符集为16gbk


oracle@linux5:/oracle>imp jiang/oracle@test2 fromuser=jiang touser=jiang file=/backup/test1.dmp log=/backup/testimp.log


Import: Release 11.2.0.4.0 - Production on 星期一 11月 28 17:28:32 2016


Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.



连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options


经由常规路径由 EXPORT:V11.02.00 创建的导出文件

已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入

. . 正在导入表 "TEST"导入了 2 行

成功终止导入, 没有出现警告。

oracle@linux5:/oracle>



SQL> select * from test;


COL1 COL2

---------- ----------

2 ???

1 中国

SQL> select col1,dump(col2,1016) from test;


COL1

----------

DUMP(COL2,1016)

--------------------------------------------------------------------------------

2

Typ=1 Len=4 CharacterSet=ZHS16GBK: a3,bf,3f,3f


1

Typ=1 Len=4 CharacterSet=ZHS16GBK: d6,d0,b9,fa ------------2个字节一个汉字, 16gbk编码存储 数据库做了数字编码转换工作。



SQL>







参考 http://blog.csdn.net/wuweilong/article/details/39694531

源端数据库test1 (1)字符集为utf8 →EXP客户端(2)→IMP客户端(3)→目标数据库(4) test2字符集为16gbk,

数据在迁移过程中要经历如上的4个点,数据在流动过程中(如上的3个箭头)需要依次比较箭头两端的字符集,

如果相同则不转换,如果不同则进行转换。如果相邻的两个点之间设置的字符集均不相同,则需要转换3次。

最好的设置方式是,因为(1)(4)数据库的字符集是固定的,则设置客户端的字符集(2)(3)均与(1)相同,

这样最多只在(3)→(4)的过程中发生一次字符集的转换。但是前提是(4)的字符集必须是(1)的的字符集的超集。客户端字符集是通过环境变量NLS_LANG来设置。




写入数据----字符转换过程


数据库端通过简单的判断跟 客户端环境变量的字符集 是否一致进行字符转换 一致则不转换,直接存储到数据库中,不一致则字符转换。

客户端的字符集的作用就是告知数据库端传输的字符编码


数据库看到客户端的字符集和数据库的字符集一致,此时oracle将不会再对字符作转换,因为它认为两边的字符编码是一致的。而此时,

我们欺骗了数据库,尽管我们将客户端字符集设置为和数据库一致,但是其实我们使用的windows7是zhs16gbk字符集编码(因为此时windows使用的就是这个字符编码),

对于字符"中国",zhs16gbk字符集里对应的编码为d6,d0,b9,fa。此时,oracle不加理会的直接将这个编码保存到了数据库中。




查找数据----字符转换过程(win7 16gbk一定)


当session 1开始查询时,oracle从表中取出这两个字符,并按照字符集al32utf8和字符集zhs16gbk的编码映射表,将它的转换成zhs16gbk字符编码,对于编码"e4,b8,ad,e5,9b,bd",

它对应的zhs16gbk的字符编码为"d6,d0,b9,fa",这个编码对应的字符为"中国",所以我们看到了这个字符正常显示出来了,3---2


而对于字符集存储的al32utf8字符编码"d6,d0,b9,fa",

由于我们用于显示字符的windows环境使用的是zhs16gbk字符集,而在zhs16gbk字符集里面并没有对应这个编码的字符或者属于无法显示的符号,utf8---16gbk 转换找不到

于是使用了"?"这样的字符来替换,这就是为什么我们看到session 2输入的字符变成了这样的乱码。
































字符 字符集 数据 数据库 编码 客户 客户端 正在 中国 存储 一致 输入 过程 相同 两个 端的 字节 就是 环境 查询 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网是第几次科技革命的成果 互联网科技工作委员会副主任毛军 互联网金融监管科技数据 关于新基建和互联网科技 期待互联网科技 天津摩尔互联网科技 互联网巨头投资的硬核科技 互联网系的金融科技公司 互联网软件和科技 南平创想时代互联网科技有限公司 千方科技属于互联网企业吗 杭州壁岐互联网科技有限公司 明优互联网科技有限公司 区块链结合互联网科技 滨湖区互联网智能科技产品有哪些 国产互联网科技公司 互联网高科技行业有哪些企业 互联网大会出现的黑科技 高科技和互联网的现代国家 广州全民伙伴互联网科技有限公司 互联网科技股 奇士达互联网科技 互联网科技有限公司 翻译 中国科技互联网公司收入 互联网科技热点资讯 互联网金融中的现代科技 互联网科技创新的路径 华中科技大学互联网的牛人 山东有哪些互联网科技公司 张家口科技产业互联网平台
0