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输入的字符变成了这样的乱码。

         

         

 

         

 

 

         

            

      

         

      

  

           

网页名称:oracle数据库字符集
链接分享:https://www.cdcxhl.com/article2/jooeoc.html

成都网站建设公司_创新互联,为您提供关键词优化网站营销用户体验定制网站企业网站制作服务器托管

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

小程序开发