操作clob 大字段的can bind a LONG value only for insert into a LONG column 异常处理

 开发架构:spring 2.0

 DAO层:ibatis 2.3

 DB: oracle 10g

需要在spring的application.xml的关于clob的配置。如下源码:

==========================================

 <!-- spring提供的对ibatis大字段处理  -->
    <bean id="nativeJdbcExtractorNew" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor" lazy-init="true"/>
  
  
    <bean id="oracleLobHandlerNew" class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true">
     <property name="nativeJdbcExtractor"><ref local="nativeJdbcExtractorNew"/></property>
 </bean> 
   
    <!-- SqlMap setup for iBATIS Database Layer -->
    <bean id="sqlMapClientNew" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
     <property name="dataSource" ref="dataSourceNew" />
  <!-- 大字段处理 -->
  <property name="lobHandler"><ref local="oracleLobHandlerNew"/></property>
   </bean>

============================================

对clob的操作出现can bind a LONG value only for insert into a LONG column ,主要问题是在引入jar包上。

先说下我做的项目中大字段出现的问题时的系统引入的jar包,oracle版本:10g,用的驱动版本:classes12.jar的版本10.2.0.1.0。并且项目中同时还有ojdbc14.jar(10.02版本) 、ojdbc14dms.jar、classes12dms.jar、ojdbc14dms_g.jar这几个都设计数据库操作的jar包,Tomcat的lib下也是classes12.jar(10.2.0.1.0版本)。在项目具体模块中涉及到大字段的操作时候,始终出现can bind a LONG value only for insert into a LONG column 的sql异常。

在网上查了很多资料,都倾向于是使用的oracle版本和classes12.jar的版本不一致的问题所造成,因为项目使用的是oracle10g,换了classes12.jar(10.2.0.1.0版本)包与所使用的oracle版本一致了,但是在操作时问题依然出现sql的异常。

=================================================

解决方式:

            1.删除项目中的ojdbc14.jar(10.02版本) 、ojdbc14dms.jar、classes12dms.jar、 

              ojdbc14dms_g.jar、classes12.jar(10.2.0.1.0版本)这样的jar。

            2.同时删除tomcat/lib下的classes12.jar包。

            3.用ojdbc14.jar(注意:Oracle JDBC Driver version - 10.1.0.2.0)添加到项目和tomcat中。

重启app,操作相应的用到大字段的模块,问题解决。

================================================================

 问题的原因:

                驱动包classes12.jar用于JDK 1.2和JDK 1.3,而ojdbc14.jar用于JDK 1.4及以上,所以尽量不要使用classes12.jar;

              从oracle 9.2之后,对jdbc 的驱动程序的命名将有所改变,JDK1.1,JDK1.2的驱动程序名(class12.jar)将不再改变,一直沿用下去,从JDK1.4开始驱动程序名将所有改变,例如:JDK1.4的驱动名为ojdbc14.jar 。JDK1.5的驱动名为ojdbc15.jar  

    

ORA-01461 错误通常出现在尝试将长度超过 4000 字节的字符串插入到 `VARCHAR2` 列时,尤其是在使用某些数据库驱动程序或工具(如 ODBC、JDBC 或 PL/SQL)时。尽管目标列可能不是 `LONG` 类型,但 Oracle 数据库在处理超长字符串时可能会将其视为 `LONG` 值,从而触发该错误。 ### 常见原因 1. **插入的数据长度超过 VARCHAR2(4000 字节) 的限制**: - 当插入的字符串长度超过 4000 字节(对于 `VARCHAR2` 类型)时,Oracle 可能会将其当作 `LONG` 值处理。 - 这个问题在使用绑定变量时尤为常见,尤其是在应用程序中动态构造 SQL 语句的情况下 [^2]。 2. **使用绑定变量的方式不正确**: - 某些数据库驱动程序(如 ODBC 或 JDBC)在处理大字符串时未能正确识别数据类型,导致 Oracle 将其解释为 `LONG` 类型 [^1]。 3. **NLS 设置影响字符长度计算**: - 如果数据库使用的是多字节字符集(如 AL32UTF8),则实际存储的字节数可能超过 4000 字节,即使字符数未超过 4000 [^2]。 --- ### 解决方案 #### 1. 使用 `CLOB` 替代 `VARCHAR2` 如果数据确实需要超过 4000 字节,建议将目标列的数据类型改为 `CLOB`。`CLOB` 能够存储大量文本数据,并且不会受到 `VARCHAR2` 的长度限制 [^2]。 ```sql ALTER TABLE your_table MODIFY (your_column CLOB); ``` 随后,在插入操作中确保使用适合处理 `CLOB` 的方法,例如通过 `DBMS_LOB` 包进行操作。 #### 2. 直接拼接 SQL 而非使用绑定变量 某些情况下,绑定变量会导致 Oracle 错误地将长字符串识别为 `LONG` 类型。可以尝试直接拼接 SQL 语句以避免这个问题: ```sql INSERT INTO your_table (your_column) VALUES ('very_long_string_here'); ``` 这种方式绕过了绑定变量机制,适用于静态内容插入,但在动态内容场景下需注意 SQL 注入风险 [^1]。 #### 3. 分插入并截断数据 如果业务逻辑允许,可以将字符串截断为不超过 4000 字节的内容插入,或者分多次插入不同部分: ```sql INSERT INTO your_table (your_column) VALUES (SUBSTR('long_string', 1, 4000)); ``` #### 4. 修改客户端配置 某些数据库驱动程序支持设置参数来控制如何处理长字符串。例如在 JDBC 中,可以通过设置 `SetBigStringTryClob=true` 来强制使用 `CLOB` 处理长字符串 [^2]。 #### 5. 检查 NLS_CHARACTERSET 设置 如果数据库使用的是多字节字符集(如 UTF-8),请确认插入字符串的实际字节数是否超过了 4000 字节。可以通过以下查询检查字符集: ```sql SELECT parameter, value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET'; ``` 根据字符集情况调整输入数据的长度,确保其在字节层面符合 `VARCHAR2` 的限制。 --- ### 总结 ORA-01461 错误的核心在于 Oracle 对长字符串的处理方式与目标列的数据类型不匹配。解决方法包括更改列类型为 `CLOB`、调整绑定变量行为、优化字符集设置等。具体选择哪种方式应根据实际业务需求和系统架构决定。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值