`
daoger
  • 浏览: 530689 次
  • 性别: Icon_minigender_1
  • 来自: 山东济南
社区版块
存档分类
最新评论

Spring JDBC对Oracle10g数据库操作时RowSet的问题

阅读更多

使用Spring JDBC对Oracle10g进行数据库分页的时候出现了异常,错误信息如下:

 

[ERROR]2971656-2009-05-1815:38:24-
[com.ieslab.idp.datamaint.service.impl.DataGridServiceImpl.
buildGrid(DataGridServiceImpl.java:
171)]-[]-org.springframework.jdbc.UncategorizedSQLException: StatementCallback;
uncategorized SQLException for SQL [select * from (select temp.* ,ROWNUM num from ( 
select * from idp_pub_m.厂站_VW) temp where ROWNUM <= 4 ) where num > 0]; 
SQL state [null]; error code [0]; Invalid scale size. Cannot be less than zero; 
nested exception is java.sql.SQLException: Invalid scale size. Cannot be less than zero 
 

上面错误中,进行的操作是从一个视图中查询数据并进行分页操作,当单独执行:

select temp.* ,ROWNUM num from 
( select * from idp_pub_m.厂站_VW) temp where ROWNUM <= 4
 

时,是没有错误的,可以成功执行。有网友说是Oracle10g中对返回的结果集中数据精度的定义和9i中不同;例如同样是

 

select count(*) from ......

 

语句,在oracle 10g中使用Spring JDBC操作时就会有问题,异常信息同样是 java.sql.SQLException: Invalid scale size. Cannot be less than zero;将SQL语句写为

 

select count(*)+0  from ......

 

就可以解决。

 

这是另一个网友aggie2000 给出的解答,贴于此处,留作备忘。呵呵!

原帖地址是http://forum.springsource.org/showthread.php?t=19848

 

I have been dealing with the same problem (SQLException - "Invalid scale size. Cannot be less than zero") and believe I have arrived at a better solution for those who wish to use the Spring API as much as possible.

The basic problem, as I understand it, is that there is an incompatibility between Oracle and the standard CachedRowSet implementation (CachedRowSetImpl) of Java 1.5. Spring uses this implementation by default when you call queryForRowSet(...). However, this does not mean that you cannot use SqlRowSet. The SqlRowSet class doesn't know anything about the implementation of the CachedRowSet interface that you're using. The class that is actually utilizing the CachedRowSetImpl class is the ResultSetExtractor... more specifically, the SqlRowSetResultSetExtractor (this is used by Spring when you call queryForRowSet).

In order to achieve the same result (returning a Spring SqlRowSet), you can pass in your own ResultSetExtractor to the query(...) methods (*not* queryForRowSet) that take a ResultSetExtractor as a parameter. What I did was just clone the SqlRowSetResultSetExtractor and instead of using the standard CachedRowSetImpl class, I replaced it with Oracle's CachedRowSet implementation. This way, when the ResultSet is mapped to a CachedRowSet, it uses Oracle's implementation to do so and thus the incompatibility is eliminated. Here is my ResultSetExtractor class that does just that...
-------------------------

package com.yada.yada.yada;

import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.rowset.CachedRowSet;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.support.rowset.ResultSetW rappingSqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import oracle.jdbc.rowset.OracleCachedRowSet;

public class SqlRowSetOracleResultSetExtractor implements ResultSetExtractor {

public Object extractData(ResultSet rs) throws SQLException {
return createSqlRowSet(rs);
}

/**
* Create a SqlRowSet that wraps the given ResultSet,
* representing its data in a disconnected fashion.
* <p>This implementation creates a Spring ResultSetWrappingSqlRowSet
* instance that wraps a standard JDBC CachedRowSet instance.
* Can be overridden to use a different implementation.
* @param rs the original ResultSet (connected)
* @return the disconnected SqlRowSet
* @throws SQLException if thrown by JDBC methods
* @see #newCachedRowSet
* @see org.springframework.jdbc.support.rowset.ResultSetW rappingSqlRowSet
*/
protected SqlRowSet createSqlRowSet(ResultSet rs) throws SQLException {
CachedRowSet rowSet = newCachedRowSet();
rowSet.populate(rs);
return new ResultSetWrappingSqlRowSet(rowSet);
}

/**
* Create a new CachedRowSet instance, to be populated by
* the <code>createSqlRowSet</code> implementation.
* <p>This implementation creates a new instance of
* Oracle's <code>oracle.jdbc.rowset.OracleCachedRowSet</code> class,
* which is their implementation of the Java 1.5 CachedRowSet interface.
* @return a new CachedRowSet instance
* @throws SQLException if thrown by JDBC methods
* @see #createSqlRowSet
* @see oracle.jdbc.rowset.OracleCachedRowSet
*/
protected CachedRowSet newCachedRowSet() throws SQLException {
return new OracleCachedRowSet();
}

}
 


-------------------------
You can pass this to the various query methods like so:

SqlRowSet sqlRowSet = (SqlRowSet)jdbcTemplate.query(sql,
 new SqlRowSetOracleResultSetExtractor());


Hope that helps! Seems to be working for me.

 

我按照aggie2000 给出的回复解决了这个问题,上面的代码中引用的几个类在Oracle10g的驱动ojdbc14.jar中。至于具体原因,aggie2000 已经给出了答案,欢迎对这个问题熟悉的朋友,回复讨论。

 

 

 

 

 

 

1
1
分享到:
评论

相关推荐

    <<Java数据库高级编程宝典>>配套光盘

    8. Spring Data JPA与MyBatis:Spring框架中的数据访问层解决方案,如Spring Data JPA和MyBatis,使得数据库操作更加简洁和高效。 通过《Java数据库高级编程宝典》的配套光盘,读者不仅可以学习到JDBC的基础知识,...

    spring jdbctemplate 封裝

    import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.jdbc.support.rowset.SqlRowSetMetaData; ...

    myBatis01.pdf

    Configuration Layer负责加载数据库配置信息,SqlSession Layer负责提供对数据库的访问接口,而Executor Layer负责执行SQL语句。 1.1.2 MyBatis与J2EE MyBatis支持J2EE规范,能够与J2EE应用程序集成,提供了简洁的...

    j2ee学习路径 对初学者很有帮助

    3. **JDBC**:Java数据库连接(JDBC)是与数据库交互的基础,需要了解JDBC的基础知识,如连接池的使用,如何利用DataSource和RowSet进行数据操作,以及如何通过JDBC连接Oracle和MySQL。 4. **Web前端技术**:HTML、...

    java自学路线图java自学路线图.doc

    掌握不同数据库(如Oracle和MySQL)的JDBC特定操作。 4. **HTML/CSS/JavaScript**:HTML用于网页结构,CSS用于样式,JavaScript负责交互。理解基础语法,掌握表单验证、DOM编程(事件处理)以及常见JavaScript效果...

    Java自学知识点参考.doc

    2. **数据库**: 掌握SQL语言,包括对Oracle或MySQL的操作,如单表查询、多表连接(内连接、外连接)、子查询。管理数据库对象如表、视图、索引、序列和约束。树状结构存储数据,学习存储过程和触发器的创建和调用。 ...

    java 学习方向 个人整理

    要熟悉连接池的使用,如C3P0或DBCP,理解DataSource和RowSet,以及Oracle和MySQL的连接方式。 4. **HTML/CSS/JavaScript**:网页制作的三大基础,HTML负责内容结构,CSS负责样式表现,JavaScript负责交互行为。...

    java自学之路num1

    3. **JDBC**:Java数据库连接,用于与数据库交互。理解JDBC的基础,如建立连接、执行SQL、处理结果集。掌握连接池(如C3P0、DBCP、HikariCP)的使用,以及DataSource和RowSet接口。针对Oracle和MySQL,熟悉其特定的...

    java学习流程介绍以及java核心思想

    3. **JDBC(Java Database Connectivity)**:JDBC是Java连接数据库的标准接口,包括基础的数据库连接、数据源DataSource和RowSet的使用。理解JDBC连接Oracle和MySQL的差异。 4. **Web前端技术**:HTML、CSS和...

    J2EE学习路线及重要知识点.pdf

    3. **JDBC**:学习JDBC基础知识,如连接数据库,执行SQL,处理结果集,理解连接池的概念,使用DataSource和RowSet,以及针对Oracle和MySQL的特定操作。 4. **前端技术**:HTML,CSS,JavaScript的基本语法,用于...

    J2EE软件工程师内部培训资料

    - **JDBC对标准的扩展(JNDI)**:介绍如何使用Java命名和目录接口(JNDI)来查找和获取数据库连接。 #### Hibernate 3.0 - **Hibernate的简介**:概述Hibernate框架的核心概念和优势。 - **Hibernate的工作原理**:...

    JAVA自学之路 七路线图明细

    掌握RowSet和ResultSet的使用,以及与Oracle和MySQL的JDBC连接。 5. **HTML/CSS/JavaScript**:熟悉HTML、CSS和JavaScript的基本语法,理解DOM编程和事件处理。学习如何使用JavaScript实现常见效果,如TreeView和...

    J2EE课程总结

    - JDBC提供了多种异常类型来处理数据库操作中可能出现的问题。 **4. JDBC中的事务** - 通过设置`Connection`对象的事务隔离级别和自动提交状态来控制事务行为。 **5. JDBC2.0新特性** - 包括Statement接口的改进、...

    J2EE学习路线及重要知识点

    - **DataSource&RowSet**:`DataSource`接口提供了一种获取数据库连接的标准化方式,而`RowSet`提供了离线操作数据集的能力。 #### 四、前端技术(HTML、CSS、JavaScript) - **HTML/CSS**:HTML用于定义网页结构,...

    java_学习路线图

    - **JDBC API**:了解如何使用JDBC进行数据库操作。 - **连接池技术**:如DataSource、RowSet等,提高数据库访问效率。 - **Oracle/MySQL**:具体实现与这些数据库的交互。 #### 四、前端技术基础 - **...

    java自学路线

    - **Oracle与MySQL**:对比这两种流行的数据库管理系统,并介绍其基本操作命令。 - **SQL语言**:熟练使用SQL进行数据查询、插入、更新和删除操作。 - **事务处理**:理解事务的概念及其在实际业务中的应用。 #### ...

    java学习路线图 java学习路线图

    学习资源包括书籍和视频,如《Java就业培训教程》、《Java就业培训教程视频》、《从实践中学习Oracle/SQL》和《传智播客JDBC视频》等。 4. **Web开发基础**: - **HTML/CSS/JavaScript**:掌握网页开发的基础,...

Global site tag (gtag.js) - Google Analytics