java.sql.SQLException:使用IN运算符时的数字溢出

时间:2013-05-15 15:48:16

标签: java sql oracle jdbc sqlexception

我实现了一个Java应用程序,它使用查询基于给定的id集查询数据库:

select * from STUDENT where ID in (?)

这组ID将用于替换?。但是,偶尔会收到一个例外:

Caused by: java.sql.SQLException: Numeric Overflow
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:199)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:263)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:271)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:445)
at oracle.jdbc.driver.NumberCommonAccessor.throwOverflow(NumberCommonAccessor.java:4319)
at oracle.jdbc.driver.NumberCommonAccessor.getInt(NumberCommonAccessor.java:187)
at oracle.jdbc.driver.OracleResultSetImpl.getInt(OracleResultSetImpl.java:712)
at oracle.jdbc.driver.OracleResultSet.getInt(OracleResultSet.java:434)

经过一些测试,我意识到如果我将id列表分成许多较小的子列表,异常就会停止。出于某种原因,jdbc不喜欢将过多的值放入IN (?)。我想知道是否有人以前见过这个问题,并对此有解释?由于这个问题从未发生在生产环境上,而只发生在本地问题上(资源功能较少),我怀疑它与服务器资源有关。

由于

更新:我正在使用的源代码是:

// create a query
private String getQueryString(int numOfParams) {
    StringBuilder out = new StringBuilder();
    out.append("select * from STUDENT where ID in (");
    for (int i = 0; i < numOfParams; i++) {
        if (i == numOfParams - 1) {
            out.append("?");
        } else {
            out.append("?, ");
        }
    }
    out.append(")");
}

// set parameters
private void setParams(PreparedStatement ps, Set<String> params) {
    int index = 1;
    for (String param: params) {
        ps.setString(index++, param);
    }
}

public void queryStudent(Connection conn, Set<String> ids) throws Exception {
    String query = this.getQueryString(ids.size());
    PreparedStatement ps = conn.prepareStatement(query);
    this.setParams(ps, ids);
    ps.executeQuery();

    // do some operations with the result
}

3 个答案:

答案 0 :(得分:3)

问题是由GlassFish和应用程序之间的ojdbc驱动程序冲突引起的。为了解决这个问题,我需要:

  • 更新应用程序的pom.xml(因为我正在使用maven)使用最新版本 ojdbc是ojdbc6-11.2.0.3
  • 将ojdbc6-11.2.0.3添加到GlassFish lib
  • 如有必要,请手动从glassfish中已部署的应用程序库中删除ojdbc jar(显然这不是取消部署所清除)

答案 1 :(得分:0)

您是否检查过MySQL和/或JDBC max packet size设置?这通常会给你带来大量的IN(...)列表。

答案 2 :(得分:0)

这会发生在您的实体的ID属性或其他一些整数属性类型中 看看你的堆栈跟踪&gt;

at oracle.jdbc.driver.NumberCommonAccessor.getInt(NumberCommonAccessor.java:187)
at oracle.jdbc.driver.OracleResultSetImpl.getInt(OracleResultSetImpl.java:712)
at oracle.jdbc.driver.OracleResultSet.getInt(OracleResultSet.java:434)

查询返回的任何值都不适合此属性! 更改属性Integer并尝试在实体的所有Integer类型字段中使用下一个整数类型(long,Long BigInteger)。