【问题标题】:JDBC result set from an Oracle PL/SQL stored procedure来自 Oracle PL/SQL 存储过程的 JDBC 结果集
【发布时间】:2023-03-05 11:29:01
【问题描述】:

oracleClose() 和 oracleCloseQuery() 在 sqlj.runtime.ExecutionContext.OracleContext 中做了什么。

由于我们在 finally 块中使用 oracleClose() 将 jdbc 驱动程序 jar 升级到 ojdbc5.jar,因此在使用 resultset.next() 而不是 oracleCloseQuery() 时出现以下异常。使用oracleCloseQuery() 是否安全。数据库是 Oracle 11g 和 WAS 6.1.X.X。感谢您的回复。 这是错误消息:

java.sql.SQLException: Closed Statement: next 在 oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70) 在 oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:131) 在 oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:197) 在 oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:261) 在 oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:269) 在 oracle.jdbc.driver.OracleResultSetImpl.next(OracleResultSetImpl.java:205) 在 com.westgroup.pubsvc.rms.models.ResultSetSRC.getNextResult(ResultSetSRC.java:112)

【问题讨论】:

    标签: java oracle jdbc oracle11g


    【解决方案1】:

    异常告诉您,在您尝试迭代 ResultSet 时,返回此 ResultSetStatement 已关闭。这表明您在执行Statementtry外部使用ResultSet,并且您可能使用ResultSet 作为该方法的返回值。这是一种不好的做法

    我建议您重写 JDBC 代码,以便在执行 Statement 时在相同的 try 块中处理 ResultSet,或者这些方法返回类似于 List<Entity> 的内容而不是ResultSet

    这是正确 JDBC 习惯用法的启动示例:

    public List<Entity> list() throws SQLException {
        // Declare resources.
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        List<Entity> entities = new ArrayList<Entity>();
    
        try {
            // Acquire resources.
            connection = database.getConnection();
            statement = connection.createStatement("SELECT id, name, value FROM entity");
            resultSet = statement.executeQuery();
    
            // Gather data.
            while (resultSet.next()) {
                Entity entity = new Entity(); 
                entity.setId(resultSet.getLong("id"));
                entity.setName(resultSet.getString("name"));
                entity.setValue(resultSet.getInteger("value"));
                entities.add(entity);
            }
        } finally {
            // Close resources in reversed order.
            if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
            if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
            if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
        }
    
        // Return data.
        return entities;
    }
    

    顺便说一下,这里不需要 Oracle JDBC 驱动程序特定的类/方法。这只是java.sql.*。这样您就可以在数据库之间保持 JDBC 代码的可移植性。

    【讨论】:

    • 感谢您的回复。该方法返回结果集,并在 finally 块执行后稍后使用,这不是一个好的做法,但适用于 Oracle JDBC 驱动程序版本 - “10.2.0.1.0”。而这段代码是Jpublisher从存储过程中生成的java代码。那么这是否意味着我们需要更改存储过程。
    • 我不确定 JPublisher 都在做什么,但是在这样的方法之外传递 ResultSet 是个坏主意。您不需要更改存储过程。您只需将ResultSet 映射到List&lt;Entity&gt;,如答案所示。
    猜你喜欢
    • 2011-05-21
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    相关资源
    最近更新 更多