一次ORACLE字符转换分析过程

来源:这里教程网 时间:2026-03-03 16:39:03 作者:

一、 现象描述

  在aix数据库上创建如下表时,varchar2字段类型变成了varchar2( char);                                               

一、补充varchar2 varchar2( char) 的区别

      varchar2(byte)/varchar2() :就是默认的表示方式,比如我们写成:varchar2(100),就相当于varchar2(100 byte),表示最大字节数是100,该字段最多能容纳100个字节,强调空间大小。由于我们描述的是字节,因此,保存汉字等字符时,就要小心了。如果你的数据库用的是GBK编码,那么一个汉字将占用2个字节,最多能存50个汉字,如果你的数据库用的是UTF8编码,那么一个汉字将占用3个字节,最多能存33个汉字。 

     varchar2(char) :表示最大字符数是100,该字段最多能容纳100个字符,强调个数。假设我们写成varchar2(100 char),那么无论是数字、字母、汉字,都看成一个字符,最多写100个,当然,汉字越多,占用的空间越大,同样遵循上边的数据库编码原则。例如:存入一个汉字,底层占2或3个字节,存入一个字母,占1个字节,绝对不是某些文章所说1个字母或数字也占2或3个字节! 

二、 影响

varchar2() 和varchar2() 的字符数量最大都是4000,即varchar2(4000)和varchar2(4000)是一样的,但是在其他情况下,比如varchar2(40 char) >= varchar2(40) ,如果从varchr2(40 cahr) 的表导出数据到varchar2(40) 将可能导致导入报错:ORA-12899 字段长度不够。

 

三、 问题原因

 

导致该问题的原因是nls_length_semantics参数的设置。

set line 150   col parameter for a40   col value for a40   select * from nls_database_parameters where   parameter=upper('nls_length_semantics');

 

四、 相关实验

实验:

 

实验新建用户troy,新建两张表,test1在nls_length_semantic=char情况下建立,test6在nls_length_semantic=byte情况下建立。

实验情况如下:

 

nls_length_semantics 为char的情况:

 

nls_length_semantics 为byte的情况:

 

从dbms包取出来的建表语句也可反映出这种差别;    

查询实验

 

下面的实验为补充实验,分别在nls_length_semantic=char 和nls_length_semantic=byte的情况下,在plsql中查询对应表的建表语句:

##test1 是在char的时候建立,test6是在 byte的情况下建立:

这个比较有意思: 

4.2.1 使用dbms 包查询:

在nls_length_semantic=char 和nls_length_semantic=byte 的情况是一样的,如下图:

 

4.2.2 使用右键查看创建sql 的方式

在nls_length_semantic=byte的情况下    

在nls_length_semantic=char的情况下:有了varchar2(byte)这个类型   

五、解决方案

1 建议linux数据库nls_length_semantic变量和aix数据库保持一致。毕竟aix生产库已经有大量数据。更改较为麻烦;命令如下:

alter system set nls_length_semantic=char;shutdown immediate;startup; 

 

相关推荐