日期:2014-05-16 浏览次数:20721 次
今天上午,之前测试都没有问题的过程,今天报错ora-06052的异常,查询之后发现原来是同一个字段在不同的表中定义的长度不一样,一个表中定义的是512,另一个表中定义的是500,现在分别用这两个字段定义了两个变量,当用512的变量给500的变量赋值时,如果赋值超过500就出问题了(确实超过500)。
随后我查了一下char,varchar,varchar,nvarchar这四种字符类型,以及这四种类型在utf8和gbk两种字符集下存储中文的情况,length和lengthb函数。
ora-12899:是向表中插入的值超过了字段的长度。
ora-06052:是在赋值时值超过了变量的长度。
length:统计的是字符串中字符的个数。
lengthb:统计的是字符串的字节数。
char2(10),varchar(10),varchar2(10)的字段:
在gbk数据库中可以存5个汉字,lengthb统计到每个汉字是2个字节。
在utf8数据库中可以存3个汉字,lengthb统计到每个汉字是3个字节。
nvarchar2(10)的字段:
在gbk数据库中可以存10个汉字。
在utf8数据库中可以存10个汉字。
-----------------------------------------
char:定长字符型,[1,2000]字节,不足则在后面补空格。
varchar:不定长字符型,[1,2000]字节。
varchar2:不定长字符型,[1,4000]字节,在pl/sql中最大长度是32767(没有测试)。
nvarchar:不定长字符型,[1,4000]字符。从下面测试情况看,在这两个不同字符集中都是按照2个字节来存储数据。
--这个地方不明白,utf8下不是每个汉字三个字节吗,怎么这里是两个字节。
---下面是测试语句
--查看数据库服务端的字符集
select userenv('language') from dual;
--查看dmp的字符集
select nls_charset_name(to_number('0354','xxxx')) from dual;
--查看数据库字符集
select * from nls_database_parameters;
--查看客户端字符集
select * from nls_instance_parameters;
--查看会话字符集
select * from nls_session_parameters;
drop table ttt1 purge;
drop table ttt2 purge;
drop table ttt3 purge;
drop table ttt4 purge;
create table ttt1(name char(10));
insert into ttt1 values('123');
insert into ttt1 values('我爱你');
insert into ttt1 values('我爱你我你');
select name,length(name),lengthb(name),dump(name) from ttt1;
create table ttt2(name varchar(10));
insert into ttt2 values('123');
insert into ttt2 values('我爱你');
insert into ttt2 values('我爱你我爱你');
insert into ttt2 values('我爱你我你');
select name,length(name),lengthb(name),dump(name) from ttt2;
create table ttt3(name varchar2(10));
insert into ttt3 values('123');
insert into ttt3 values('我爱你');
insert into ttt3 values('我爱你我爱你');
insert into ttt3 values('我爱你我你');
select name,length(name),lengthb(name),dump(name) from ttt3;
create table ttt4(name nvarchar2(10));
insert into ttt4 values('123');
insert into ttt4 values('我爱你');
insert into ttt4 values('我爱你我爱你');
insert into ttt4 values('我爱你我你');
insert into ttt4 values('我爱你我你我爱你我你');
insert into ttt4 values('我爱你我你我爱你我你1');
select name,length(name),lengthb(name),dump(name) from ttt4;
commit;
在gbk字符集数据库中测试的结果
SQL> --查看数据库服务端的字符集
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
SQL> --查看dmp的字符集
SQL> select nls_charset_name(to_number('0354','xxxx')) from dual;
NLS_CHARSET_NAME(TO_NUMBER('03
----------------------------------------
ZHS16GBK
SQL> --查看数据库字符集
SQL> select * from nls_database_parameters;
PARAMETER VALUE
------------------------------ --------------------------------------------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CHARACTERSET ZHS16GBK
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY $
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_RDBMS_VERSION 10.2.0.4.0