Oracle转换字符集操作到底发生了什么?
数据库当前字符集为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转换字符集操作到底发生了什么?的更多相关文章
- Oracle数据库字符集问题解析
Oracle数据库字符集问题解析 经常看到一些朋友问ORACLE字符集方面的问题,我想以迭代的方式来介绍一下.第一次迭代:掌握字符集方面的基本概念.有些朋友可能会认为这是多此一举,但实际上正是由于对相 ...
- Oracle数据库字符集问题
Oracle数据库的字符集问题,也涉及作为服务器操作系统的CentOS或者Windows的字符集与Oracle字符集之间的关联关系Oracle的字符集,这个问题的提出是因为两个原因:一是遇到一个DMP ...
- [转]sqlldr 导入乱码,Oracle客户端字符集问题
1,查Oracle数据库创建时候的字符集:oracle服务器端执行 SQL> select name, value$ from sys.props$ where name like 'NLS%' ...
- 选择ORACLE数据库字符集
如何选择数据库的字符集是一个有争议的话题,字符集本身涉及的范围很广,它与应用程序.客户的本地环境.操作系统.服务器等关系很密切,因此要做出合适的 选择,需要明白这些因素之间的关系.另外对字符集的基本概 ...
- oracle数据库字符集
Oracle字符集的基本原理 1. Oracle服务器字符集 oracle以哪种字符编码存储字符,可以通过以下语句查出数据库字符集的设置. 方法1 SQL> select * from v$nl ...
- oracle的字符集设置与乱码
oracle的字符集设置与乱码 字符集问题一直叫人头疼,究其原因还是不能完全明白其运作原理. 在整个运行环节中,字符集在3个环节中发挥作用: 1.软件在操作系统上运作时的对用户的显示,此时采用操作系统 ...
- Js new到底发生了什么
在Js中,我们使用了new关键字来进行实例化 那么在这个new的过程中到底发生了什么? 关于构造函数的return 正常来讲构造函数中是不用写return语句的,因为它会默认返回新创建的对象. 但是, ...
- Oracle数据库字符集修改
Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系.ORACLE支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据.一般来说,数据库字符集在安装数据库实例时就 ...
- 转:php连接oracle设定字符集,避免乱码
原文来自于:http://muyu.iteye.com/blog/399884 数据库用oracle,当php连接oracle的时候,最好指定字符集. 查PHP手册,oci_connect的第四个参数 ...
随机推荐
- Postgresql中无则插入的使用方法INSERT INTO WHERE NOT EXISTS
一.问题 Postgresql中无则插入的使用方法INSERT INTO WHERE NOT EXISTS,用法请参考样例. 二.解决方案 (1)PostgresSQL INSERT INTO tes ...
- Linux 目录简介
这里以Centos7为例: 使用tree命令查看/目录结构如下: 下面我们主要探讨如下主要目录: /:根目录不必多说,文件系统的最顶端,存放系统所有目录. bin:该目录主要存放系统运行所需要的重要命 ...
- Java集合大全
上图为整理的集合类图关系,带对号标志的为线程安全类. 区别说明: 1.List Set Map Queue的区别List: 有序,可以多个元素引用相同的对象Set: 无序,不重复,不可以多个元素引用相 ...
- SpringBoot健康检查实现原理
相信看完之前文章的同学都知道了SpringBoot自动装配的套路了,直接看spring.factories文件,当我们使用的时候只需要引入如下依赖 <dependency> <gro ...
- new的原理及实现
new的过程 // new运算的过程 /** * 1.创建一个空对象: * 2.该空对象的原型指向构造函数(链接原型):将构造函数的 prototype 赋值给对象的 __proto__属性: * 3 ...
- Qt之Q_PROPERTY宏理解
在初学Qt的过程中,时不时地要通过F2快捷键来查看QT类的定义,发现类定义中有许多Q_PROPERTY的东西,比如最常用的QWidget的类定义: Qt中的Q_PROPERTY宏在Qt中是很常用的,那 ...
- ThinkPHP3.2.3:使用模块映射隐藏后台真实访问地址(如:替换url里的admin字眼)
例如:项目应用目录/Application下模块如下,默认后台模块为Admin 现在需要修改后台模块的访问地址,以防被别有用心的人很容易就猜到,然后各种乱搞... (在公共配置文件/Applicati ...
- AIX—日常运维命令总结
1. 查看AIX服务器的物理构造信息,包括服务器网络配置信息 # prtconf # ifconfig -a # lsattr -E -l mem0 :查看系统内存大小 # netstat -in : ...
- mysql主从复制几个重要的参数
1. relay_log_recovery = 1 当slave从库宕机后,假如relay-log损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的relay-log,并且重新从master上 ...
- 使用springboot集成腾讯云短信服务,解决配置文件读取乱码问题
springboot集成腾讯云短信服务: (1)导入依赖 <dependency> <groupId>org.springframework.boot</groupId& ...