数据库当前字符集为AL32UTF8,若打算将字符集更换为ZHS16GBK,执行如下命令:

"ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE ZHS16GBK"

可以达到预期目标吗?

我们通过一个实验来看一看,执行上述命令,在数据库层面到底发生了什么。

在字符集为AL32UTF8的数据库中,创建一张表,分两个字段分别插入一些汉字和一些可打印的字符。

1、创建表

  create table TEST

(

id NUMBER, --记录编号

name VARCHAR2(10 CHAR),--插入随机生成的汉字串。生成方法见附件一。

key VARCHAR2(60) –插入随机生成的可打印字符串

)

2、插入50000条记录

declare

leng number;

begin

for x in 1..5

loop

for y in 1..10000

loop

leng:=ceil(dbms_random.value(0,10));

insert into test values (y,gen_hanzi(leng),dbms_random.string('P',leng));

end loop;

commit;

end loop;

end;

3、随机查看一些记录值,以及在该字符集下的编码

查询汉字"擂"的UTF8编码,

可知,数据库当前对汉字确实是使用UTF8进行编码。

4、数据库执行转换字符集命令

转换之后,查询当前数据库的字符集:

可知,在数据字典层面,数据库的字符集已合AL32UTF8转为了ZHS16GBK。

数据字典层面进行了调整,那么字符的编码有没有根据新的字符集进行调整呢?

可以看到,所有的DUMP值均没有发生变化——即在磁盘存储层面,信息未发生任何变化。因为存储上仍然在使用UTF8编码,但解码上使用GBK解码,所以,汉字全部解码错误(即没有得到正确的汉字符号)。而对于可打印的字符,由于字符在两种不同的字符集中,其编码值一致,因此,未发生解码错误。

从上述可知,如果目标字符集不是原字符集的超集,因为原编码并未发生变化,则极有可能出现解码错误而导致乱码的现象。在上面,看到了相关汉字字符在UTF8字符集下的编码值,那么这些字符在GBK字符集下是如何编码的呢?

将该表的记录插入到使用ZHS16GBK字符集的数据库中,查看记录值及编码值:

可以看到,GBK字符集对汉字是2字节编码,而UTF8对汉字是3字节编码。

我们还有另外一个问题——修改字符集之后,对于修改之前存储的字符编码无变化,那对于之后存储的字符呢?

6、向修改字符集之后的数据库中插入汉字与可打印的字符

插入100条记录,为与之前记录区别,其ID>10000。

declare

leng number;

begin

for y in 10000..10100

loop

leng:=ceil(dbms_random.value(0,10));

insert into test values (y,gen_hanzi(leng),dbms_random.string('P',leng));

end loop;

commit;

end;

查看插入的值,以及其编码:

从第7条记录的编码长度,即可初步判断其使用了GBK的编码值。我们来验证一下:

结论:

1、执行字符集转换的命令会修改数据字典

2、执行字符集转换的命令不为使用新的字符集为之前存储的字符进行重新编码。因为如果目标字符集不是原字符集的超集,转换后可能(尤其是汉字)出现乱码。

3、执行字符集转换的命令后,将为之后输入的字符使用新的字符集进行编码。

附件——"生成随机长度汉字串的存储过程"

生成随机长度汉字串的存储过程:

create or replace function gen_hanzi(max_length number) return varchar2 as

leng number;

hanzi varchar2(1 char);

hanzis varchar2(4000):='';

begin

leng:=ceil(dbms_random.value(0,max_length));

for x in 1..leng

loop hanzi:=unistr('\'||trim(to_char(ceil(dbms_random.value(19968,40869)),'XXXX')));

hanzis:=hanzis||hanzi;

end loop;

return hanzis;

end;

Oracle转换字符集操作到底发生了什么?的更多相关文章

  1. Oracle数据库字符集问题解析

    Oracle数据库字符集问题解析 经常看到一些朋友问ORACLE字符集方面的问题,我想以迭代的方式来介绍一下.第一次迭代:掌握字符集方面的基本概念.有些朋友可能会认为这是多此一举,但实际上正是由于对相 ...

  2. Oracle数据库字符集问题

    Oracle数据库的字符集问题,也涉及作为服务器操作系统的CentOS或者Windows的字符集与Oracle字符集之间的关联关系Oracle的字符集,这个问题的提出是因为两个原因:一是遇到一个DMP ...

  3. [转]sqlldr 导入乱码,Oracle客户端字符集问题

    1,查Oracle数据库创建时候的字符集:oracle服务器端执行 SQL> select name, value$ from sys.props$ where name like 'NLS%' ...

  4. 选择ORACLE数据库字符集

    如何选择数据库的字符集是一个有争议的话题,字符集本身涉及的范围很广,它与应用程序.客户的本地环境.操作系统.服务器等关系很密切,因此要做出合适的 选择,需要明白这些因素之间的关系.另外对字符集的基本概 ...

  5. oracle数据库字符集

    Oracle字符集的基本原理 1. Oracle服务器字符集 oracle以哪种字符编码存储字符,可以通过以下语句查出数据库字符集的设置. 方法1 SQL> select * from v$nl ...

  6. oracle的字符集设置与乱码

    oracle的字符集设置与乱码 字符集问题一直叫人头疼,究其原因还是不能完全明白其运作原理. 在整个运行环节中,字符集在3个环节中发挥作用: 1.软件在操作系统上运作时的对用户的显示,此时采用操作系统 ...

  7. Js new到底发生了什么

    在Js中,我们使用了new关键字来进行实例化 那么在这个new的过程中到底发生了什么? 关于构造函数的return 正常来讲构造函数中是不用写return语句的,因为它会默认返回新创建的对象. 但是, ...

  8. Oracle数据库字符集修改

    Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系.ORACLE支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据.一般来说,数据库字符集在安装数据库实例时就 ...

  9. 转:php连接oracle设定字符集,避免乱码

    原文来自于:http://muyu.iteye.com/blog/399884 数据库用oracle,当php连接oracle的时候,最好指定字符集. 查PHP手册,oci_connect的第四个参数 ...

随机推荐

  1. Javascript 日历插件

    1. The Coolest Calendar 界面非常漂亮的一款日期选择插件,有详细的使用文档,最新版本 1.5. 点击下载    查看示例 2. DatePicker 这款日期插件支持单选.多选和 ...

  2. MVC下通过jquery的ajax调用webapi

    如题 jquery的应用,不会的自己去补. 创建一个mvc项目,新建控制器.视图如下: 其中data控制器负责向前台提供数据,home控制器是一个简单的访问页控制器. data控制器代码如下: pub ...

  3. Java常用类object详解

    1.Object概述: 类Object是类层次结构的根类.每个类都使用Object作为超类.所有对象(包括数组)都实现这个类的方法. 2.构造方法详细信息: Object只有一个无参构造方法,因为ob ...

  4. web的应用模式

    在开发web应用中,有两种模式: 1.前后端分离. 2.前后端不分离. 一.前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果是有后端控制的,由后端渲染页面或重定向,也就是后端需要控制前端的 ...

  5. 阿里云查看本服务器 公网ip地址 命令

    阿里云的服务器用命令ifconfig查看的是本机内网地址 那如何访问公网地址呢? curl httpbin.org/ip

  6. 是否忘记了向源中添加“#include "StdAfx.h"”?

    错误分析 此错误发生的原因是编译器在寻找预编译指示头文件(默认#include "stdafx.h")时,文件未预期结束.没有找到预编译指示信息的头文件"stdafx.h ...

  7. Odoo form视图详解

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826350.html 一:Header头部 header区域一般用于展示文档流转的阶段和生命周期,以及动作 ...

  8. Redis开启远程访问及密码

    一.开启远程访问 1.开放端口 firewall-cmd --zone=public --add-port=6379 firewall-cmd --zone=public --add-port=637 ...

  9. Nginx 反向代理功能-动静分离

    Nginx 反向代理功能-动静分离 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  10. Oracle ASMCMD命令参考

    Oracle ASMCMD命令参考 0.什么是asm ASM它提供了以平台无关的文件系统.逻辑卷管理以及软RAID服务.ASM可以支持条带化和磁盘镜像,从而实现了在数据库被加载的情况下添加或移除磁盘以 ...