最近在做一个项目,原先是用Mysql数据库开发的,现在因客户要求,迁移到oracle。
开发的环境是,wsi(webwork+spring+ibaits).
数据库的字符集是UTF-8.
迁移过程中,碰到了这样一个问题,向一个表中执行update和insert操作时,类型为CLOB列的就出现异常
异常为:
仅可以为插入 LONG 列的 LONG 值赋值 CLOB
............
当时上网查了,有很多人也碰到了相同的问题,总体而言有两种解决方式,
第一种是驱动版本过低。
第二种是修改hibernate的配置文件,当时,前提是你开发的持久层必须是hibernate。
我从oracle官方网站下了一个最新的JDBC驱动(通过附件上传了),运行还是报哪个错误。没有效果。
而第二种方法,对于我而言,是肯定行不通的。
网上有部分人说,值长度在2000-4000之间会出现异常,
可是,我的不同,
我的是值的长度在1000-2000之间会出现异常,稍短或长都没问题。
在这里说明一下,肯定不会是因为长度限制的问题,因为CLOB在ORACLE里面,所输入的可达4G。
对于LONG,这个类型我没用过,在ORACLE里面也不建议用。是一个已经被废弃了的类型。
最后我的解决方法是,在视图层,对所输入的进行判断,把少了的用空格不上,在jsp中,四个空格等于一个字符的长度。
让其长度超过2000即可,但是,这种方法对于紧急情况可能还不错,而效率上就不说了。
还有,就是说,如果你的长度不会超过2000,就建议用varchar2,但是需要注意的是数据库字符集应该是UTF-8的,对于UTF-8或欧洲的某些字符集,oracle在存储时,对于一个字符需要2个或3个字节的存储空间,虽然表定义中varchar2(4000),但是其实该字段的data_length为其2倍或3倍长。
在这里,也顺便把在网上看到的,关于hibernate修改配置的方法,粘贴出来.
Hibernate實體對象中的数据成员类型为String,映射的数据库字段类型为org.springframework.orm.hibernate.support.ClobStringType 。實例如下:
@SuppressWarnings( " serial " )
@Entity
@Table(name = " GUIDE " )
// @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Guide {
@Type(type = " org.springframework.orm.hibernate3.support.ClobStringType " )
private String content; // 内容
// get & set
}
如果使用Spring的这个Clob类型就需要在applicationContext.xml中的sessionFactory bean里注入oracleLobHandler bean。下面給出Oracle數據庫的LobHandler配置
< bean id ="oracleLobHandler"
class ="org.springframework.jdbc.support.lob.OracleLobHandler"
lazy-init ="true" >
< property name ="nativeJdbcExtractor" ref ="nativeJdbcExtractor" />
</ bean >
< bean id ="nativeJdbcExtractor" class ="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"
lazy-init ="true" />
<!-- Hibernate SessionFactory -->
< bean id ="sessionFactory" class ="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >
< property name ="dataSource" ref ="dataSource" />
< property name ="configLocation" value ="classpath:hibernate/hibernate.cfg.xml" />
< property name ="hibernateProperties" >
< value >
</ value >
</ property >
< property name ="lobHandler" ref ="oracleLobHandler" />
</ bean >
LobHandler 需要访问本地 JDBC 对象,这一任务委托给 NativeJdbcExtractor Bean 来完成,NativeJdbcExtractor是一個本地JDBC對象抽取器,因此我們为 LobHandler 注入了一个 nativeJdbcExtractor。最后,我们把 lobHandler Bean 注入到需要进行 LOB 数据访问操作的sessionFactory Bean中或者直接注入到dao Bean中去。
大家可能已经注意到 nativeJdbcExtractor 和 oracleLobHandler Bean 都设置为 lazy-init="true",这是因为 nativeJdbcExtractor 需要通过运行期的反射机制获取底层的JDBC 对象,所以需要避免在 Spring 容器启动时就实例化这两个Bean。
如果底層數據庫是 DB2、SQL Server、MySQL 等非 Oracle 的其它數據庫,则只要简单配置一个 DefaultLobHandler 就可以了,如下所示:
< bean id ="defaultLobHandler"
class ="org.springframework.jdbc.support.lob.DefaultLobHandler"
lazy-init ="true" />
< bean id ="testDao" class ="com.test.dao.jdbc.TestJdbcDao" >
< property name ="lobHandler" ref =" defaultLobHandler" />
< property name ="jdbcTemplate" ref ="jdbcTemplate" />
</ bean >
DefaultLobHandler 只是简单地代理标准 JDBC 的 PreparedStatement 和 ResultSet 对象,由于并不需要访问数据库驱动本地的 JDBC 对象,所以它不需要 NativeJdbcExtractor 的帮助。
希望总有一张方法能帮你解决掉麻烦的ORA-01461。
如果,哪位有更好的解决方法,就麻烦分享一下了。
分享到:
相关推荐
ORA-01461 错误是 Oracle 数据库中的一种常见错误,错误信息为“仅可以为插入 LONG 列的 LONG 值赋值”。该错误通常是由于 Oracle 的 jar 包版本与 Oracle 数据库实际版本不匹配造成的。 在了解 ORA-01461 错误解决...
在处理这类问题时,有几种常见的解决方案: 1. **分块插入**: 当你的数据长度超过了4000个字符,你可以选择分批插入。例如,你可以将大字符串分割成多个小于或等于4000字符的小字符串,然后逐个插入。这可以通过...
然而,开发过程中可能会遇到错误“ORA-01461 仅可以为插入 LONG 列的 LONG 值赋值”。这个错误意味着在尝试向LONG类型的列插入数据时,操作不正确或者超出了LONG类型能容纳的最大长度。LONG列在Oracle中用于存储大...
说明:可以根据视图的text_length值设定set long 的大小 SQL>select text from user_views where view_name=upper('&view_name'); 6、同义词 查看同义词的名称 SQL>select * from user_synonyms; 7、约束...
NOT NULL约束确保列值不能为空,UNIQUE约束保证列值的唯一性,CHECK约束则限制列值必须满足特定条件。 数据库备份是数据安全的重要环节。Oracle支持物理备份(直接备份数据文件和控制文件)和逻辑备份(使用Export...
在Oracle数据库中,当需要存储超过VARCHAR2类型最大限制(4000个字符或2000个汉字)的数据时,可以使用LOB(Large Object)类型,包括BLOB(Binary Large OBject)、CLOB(Character Large OBject)以及BFILE。CLOB...
当向`CHAR` 类型的字段赋值时,如果实际值长度短于规定的长度,Oracle会在值后面填充空格来达到规定的长度。值得注意的是,如果提供的值超过规定的长度并且末尾有多余的空格,这些空格将会被移除直到符合长度要求。...
PL/SQL中的布尔变量可以通过TRUE、FALSE或NULL值进行赋值。 **2、利用SQL查询为PL/SQL变量赋值** 可以使用SELECT INTO语句将查询结果直接赋值给PL/SQL变量。 ##### 七、PL/SQL表达式与比较 **1、逻辑操作符** ...
- 可以用来存储多个字段的值。 - 示例: ```sql DECLARE TYPE dept_rec IS RECORD ( -- 定义名为dept_rec的记录类型 v_deptno DEPT.deptno%TYPE, v_dname DEPT.dname%TYPE ); dept_rec1 dept_rec; -- 定义...
Sequence是一种用于生成连续整数序列的对象,在数据库中常用于为主键自动生成唯一值。它独立于表存在,但通常与特定表的主键字段关联使用。 **创建Sequence:** - 基本语法:`CREATE SEQUENCE sequence_name ...
初始化集合时可以为其分配初始值,引用集合元素时需要指定索引或位置。 **1、引用集合中的元素** 可以通过索引或位置来访问集合中的元素。 **六、集合的赋值** 集合可以作为一个整体进行赋值,也可以单独赋值给其...
**六、集合的赋值**:可以使用赋值语句将一个集合的值复制给另一个集合。 **七、比较集合**:通过比较集合中的元素来确定两个集合是否相等。 **八、在 SQL 语句中使用 PL/SQL 的集合类型**:可以直接在 SQL 语句中...
3. **数据类型**:PL/SQL支持多种数据类型,包括数字型(如NUMBER,其子类型如BINARY_INTEGER、INTEGER等)、字符型(如VARCHAR2、CHAR、LONG、CLOB)、日期型(DATE)、布尔型(BOOLEAN)和二进制类型(如RAW和BLOB...
在Oracle中,LOB分为两类:BLOB用于存储二进制数据,而CLOB用于存储文本数据。由于Word文件通常包含文本、图片、表格等复杂元素,因此它们属于二进制数据,应使用BLOB类型存储。在Oracle中定义BLOB字段后,可以通过...
- **RAW 和 LONGRAW 值**:处理二进制数据的注意事项。 #### 第四章 PL/SQL 的控制结构 **一、PL/SQL 控制结构一览** - **概述**:提供了 PL/SQL 中可用的控制结构概览。 **二、条件控制:IF 和 CASE 语句** - **...
了解PL/SQL的数据类型是入门的第一步,包括数值型(NUMBER、INTEGER、BINARY_INTEGER)、字符型(VARCHAR2、CHAR、LONG)、日期型(DATE)、布尔型(BOOLEAN)以及各种二进制数据类型(RAW、BLOB、CLOB)。...
在插入数据后,可以使用RETURNING子句将ROWID和计算后的值返回给变量,然后通过DBMS_OUTPUT.PUT_LINE打印。 2.32 复合类型 PL/SQL的记录类型(Record)允许自定义复合数据结构。例如,定义了一个名为test_rec的...