oracle 的varchar2(4000)通过jdbc的thin驱动连接为什么只可以存666个汉字?
谁说只能存储666个汉字的?
varchar2最大是4000字节,那么就看你的oracle字符集,如果字符集是16位编码的,ZHS16GBK,那么每个字符16位,2字节,所以可以容纳2000字符。 如果是32位编码的字符集,那么只能存储 1000个字符。
从后面的例子的 length(字符长度)和lengthb(字节长度)的差别就可以看出来了。 create table T_BOARD( NAME VARCHAR2(50) insert into T_BOARD values ('测试'); select t.name,length(t.name),lengthb(t.name) from t_board t
字符集合决定varchar2的长度
问题描述: intert into T_BOARD values('超过17个汉字'); 报错:插入字符过长!发现一个汉字占3个字节,所以报错!!!
问题所在: 使用的字符集是UTF8,就有可能出现这个错误! 使用命令查看:
SQL> select parameter,value from nls_database_parameters where parameter like 'NLS_CHARACTERSET';
PARAMETER ------------------------------------------------------------ VALUE -------------------------------------------------------------------------------- NLS_CHARACTERSET AL32UTF8
解决方法: 建议使用ZHS16GBK字符集! 操作: SQL> SHUTDOWN IMMEDIATE; SQL> STARTUP MOUNT; SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION; SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; SQL> ALTER DATABASE OPEN; SQL> ALTER DATABASE CHARACTER SET AL32UTF8/ZHS16GBK;
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP; 问题解决!!! (改变时注意新的字符集是旧的超集问题)
附注1:
|
Re: 研究:为什么我的ORACLE的数据操作突然报数量限制的错误(怪)? |
发表时间: 2003-12-05 09:25 |
|
这是很经典的OracleJDBC问题。一般直接用ps.setString()设置字符串数据时,Oracle的JDBC驱动会将中文转换为2字节或3字节,不固定的,因此经常会越界。 如果你改为ps.setCharacterStream()就是固定的每个中文两个字节
|
根据oracle的文档,thin的jdbc驱动,会根据字符集合决定varchar2的长度,如果不是ascii或者拉丁字符集合,长度的限制就是2000,因为它认为其他字符集都需要两个字节来存储,但是通过jdbc的setString方法时候,驱动会把java的utf-16转换为utf-8,这样英文由两个字节变成一个字节,中文由两个字节变为3个字节,所以2000/3大概就是666个中文字符了。
附注2:
在做更新操作时,办法:
pstmt.setBytes(4,aimString.getBytes());
取数据时:
new String(resultSet.getBytes("fieldName"),"ISO-8859-1");