日期:2014-05-16 浏览次数:20636 次
今天上午,之前测试都没有问题的过程,今天报错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