vchar(4000)插入2000汉字报错

来来去去123 2011-08-18 12:02:28
用的是oracle9
有一个字段设置为vchar(4000)
hibernate 映射为: <property name="complainPosition" column="complain_position" type="string" length="4000" />
obj.set....
使用template.update(obj)
当数据str.getBytes().length >2000的时候就报错:数据大小超出此类型的最大值

客户要求允许 2000个汉字,求指导。

我不想用clob类型!

另外附上一个问题:由于这样要求的字段有两个,都必须要2000个汉字,一个字段是问题,一个字段是解决办法。
配置文件为<property name="dealSituation" column="deal_situation" type="text" />
当我用两个同时用clob的时候,当其中一个数据str.getBytes().length =2500的时候,可以正常保存。
当两个字段同时插入str.getBytes().length =2500的汉字的时候,就报错:
ORA-01483: DATE 或 NUMBER 绑定变量的长度无效

我已经疯掉了,以前用sql2000,直接在数据库里设置为text或者长度为4000的字段,都不会出现问题,
神马2000个汉字都能像我们所知道的那样正常保存。PreparedStatement对字符串的要求是不能超过2000,
可以通过stmt.setCharacterStream(1, new InputStreamReader(String内容, String内容.length());
来调整。
不过我现在是用的hibernate来保存的,虽然show_sql打印发现hibernate也是用的预处理,但我没办法调整它的长度限制。。。
求大侠来指点迷津。。。。。

经过询,我大致知道的原因是,
...全文
1867 81 打赏 收藏 转发到动态 举报
写回复
用AI写文章
81 条回复
切换为时间正序
请发表友善的回复…
发表回复
nimamamade 2011-09-07
  • 打赏
  • 举报
回复
我也出现这各问题了,不知楼主解决了没,可否细说一下解决方案?
赵4老师 2011-08-22
  • 打赏
  • 举报
回复
提醒:UTF8编码一个汉字3个字节
张文学 2011-08-22
  • 打赏
  • 举报
回复
这里有好多解决方案了. 但是LZ一个也没有试用成功的嘛?
我看着都对啊
自己学习下.
来来去去123 2011-08-22
  • 打赏
  • 举报
回复
java.sql.SQLException: 数据大小超出此类型的最大值: 3498
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
at oracle.jdbc.ttc7.TTCItem.setArrayData(TTCItem.java:147)
at oracle.jdbc.dbaccess.DBDataSetImpl.setBytesBindItem(DBDataSetImpl.java:2492)
at oracle.jdbc.driver.OraclePreparedStatement.setItem(OraclePreparedStatement.java:1194)
at oracle.jdbc.driver.OraclePreparedStatement.setString(OraclePreparedStatement.java:1614)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.setString(DelegatingPreparedStatement.java:132)
at org.hibernate.type.StringType.set(StringType.java:26)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:136)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:107)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2002)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2376)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2312)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2612)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:96)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:394)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:367)
at org.springframework.orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:636)
at org.springframework.orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:632)
at com.wri.hy.framework.application.framework.dao.hibernate.CommonDaoImpl.updateObj(CommonDaoImpl.java:237)
at com.wri.hy.jcssv3.app.web.knowledge.CaseController.save(CaseController.java:269)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.servlet.mvc.multiaction.MultiActionController.invokeNamedMethod(MultiActionController.java:433)
at org.springframework.web.servlet.mvc.multiaction.MultiActionController.handleRequestInternal(MultiActionController.java:371)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:45)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:797)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:727)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:396)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:360)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.wri.hy.framework.util.EncodingFilter.doFilter(EncodingFilter.java:70)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
来来去去123 2011-08-22
  • 打赏
  • 举报
回复
hibernate报的错误叫:

数据大小超出此类型的最大值
来来去去123 2011-08-22
  • 打赏
  • 举报
回复
[Quote=引用 69 楼 bao110908 的回复:]
很显然你用的是 UTF-8

UTF-8 的话 varchar2(4000) 只能存放 1333 个汉字,nvarchar2 最大值也只能到 1333 个汉字。
[/Quote]
执行:select vsize( '汉') from dual; 结果为2,
select * from nls_database_parameters; 结果中:
NLS_CHARACTERSET=ZHS16GBK
NLS_LENGTH_SEMANTICS=BYTE
tm47852 2011-08-22
  • 打赏
  • 举报
回复
学习了
niuniu20008 2011-08-22
  • 打赏
  • 举报
回复
投机取巧
在实体类中
在映射文件中不要写 length="4000" />

public class Test{

private String complainPosition;

public void setComplainPosition(String s){
if(s.length()>2000)
return;
else
this.complainPosition = s;
}
痞子虫 2011-08-22
  • 打赏
  • 举报
回复
ORACLE9i的版本号有
91和92

普遍用的是92版本

而92版本又分为:
9201
9204
9206
9208

你换乘9204的驱动包,应该就好了。
痞子虫 2011-08-22
  • 打赏
  • 举报
回复

你查看一下你的oracle9i的小版本号,是不是oracle 9i.2.3,然后换乘oracle 9i.2.4的驱动试试,

也就是3版本以上的驱动包,注意是小版本号。
xie3400656 2011-08-22
  • 打赏
  • 举报
回复
//我插入的时候是调用的存储过程
OracleDatabase db = (OracleDatabase)DataRegester.CreateDatabase();
OracleCommand commandWrapper = (OracleCommand)db.GetStoredProcCommand("NRGLB_Insert");

db.AddParameter(commandWrapper, "PNR", OracleType.Clob, entity.NR.Length, ParameterDirection.Input, true, 0, 0, "NR", DataRowVersion.Current, entity.NR);
handong890 2011-08-22
  • 打赏
  • 举报
回复
我以前做过一个项目遇到过这个问题感觉很诡异 插入2000就报错 2000以上以下就OK具体原因现在也忘了
解决方法就是在Hibernate实体 该字段前加上说明

@Type(type = " org.springframework.orm.hibernate3.support.ClobStringType " )
private String prdDescHtml;

当然这个是基于Spring提供的Hibernate模板来操作的

  • 打赏
  • 举报
回复
很显然你用的是 UTF-8

UTF-8 的话 varchar2(4000) 只能存放 1333 个汉字,nvarchar2 最大值也只能到 1333 个汉字。
leiting321 2011-08-21
  • 打赏
  • 举报
回复
学习路过
来来去去123 2011-08-20
  • 打赏
  • 举报
回复
57楼给出了专业的分析,不知道有没有可能在代码里面对hibernate自已的类型做个定义,让它能接受大一点的数据?
60楼,我去试试。
61楼,我觉得可行,而且看上去可以解决我的问题,如果改成GBK的,那么一个汉字就只点两个字节了,我得试试才知道。。。

当然也期待更多的回复,能给出一个最终解决办法
JikeiLiu 2011-08-20
  • 打赏
  • 举报
回复
在前插入代码处理下字符串:
  
String str=要插入的值;
if (str != null) {
byte[] bs = str.getBytes("UTF-8");
//用新的字符编码生成字符串
str= new String(bs, "GBK");
}else{
str="";
}
System.out.print(str);
lb15337109899 2011-08-20
  • 打赏
  • 举报
回复
1个汉字占两个字符
gsy999 2011-08-20
  • 打赏
  • 举报
回复
[Quote=引用 62 楼 dk_romantic 的回复:]
57楼给出了专业的分析,不知道有没有可能在代码里面对hibernate自已的类型做个定义,让它能接受大一点的数据?
60楼,我去试试。
61楼,我觉得可行,而且看上去可以解决我的问题,如果改成GBK的,那么一个汉字就只点两个字节了,我得试试才知道。。。
当然也期待更多的回复,能给出一个最终解决办法
[/Quote]
我有一个文档习作,数据使用PostgreSQL数据库,持久化使用了Hibernate,服务器用的resin.
以前做的,今天下午专门调出来试了一下. 大文本字段一条可存260k(没再加码试了).部分配置如下:

表结构:
CREATE TABLE OA_DOCUMENT(
GID AUTOINCREMENT(1,1) PRIMARY KEY,
GHEADING VARCHAR(255),
GKEYWORD VARCHAR(255),
GCOUNTER INT,
GBUILDTIME TIMESTAMP,
GUPDATETIME TIMESTAMP,
GMATTER NOTE, //这个是大文本字段
GUSERID INT,
GLOCKUP BIT,
GCONTENT_TYPE VARCHAR(255),
GSHOWSCOPE VARCHAR(255)
);
==========================================
hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="connection.datasource">java:comp/env/jdbc/DefaultDS</property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="show_sql">true</property>
<property name="hibernate.cache.user_query_cache">true</property>
<property name="hibernate.cache.use_structured_entries">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="net.sf.ehcache.configurationResourceName">ehcache.xml</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.transaction.auto_close_session">false</property>
<mapping class="gsy.document.entity.Document"/>
</session-factory>
</hibernate-configuration>

中间层DAO用泛型做的,很平常.
Document 实体类中大文本字段用的是String型.
铁匠梁 2011-08-20
  • 打赏
  • 举报
回复
UTF字符集有占用 3、4个字节的汉字。
王金豆 2011-08-20
  • 打赏
  • 举报
回复
怎么感觉像是hibernate的问题
加载更多回复(58)

81,095

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧