Java SQLException:结果集已关闭问题

Java SQLException:结果集已关闭问题,java,mysql,exception,Java,Mysql,Exception,我有一个java函数,它运行并产生一个错误。我无法理解为什么会发生这种情况,因为这是程序中第一个运行的函数,因此没有打开其他连接、语句或结果集。错误是 Operation not allowed after ResultSet closed java.sql.SQLException: Operation not allowed after ResultSet closed at com.mysql.jdbc.SQLError.createSQLException(SQLErro

我有一个java函数,它运行并产生一个错误。我无法理解为什么会发生这种情况,因为这是程序中第一个运行的函数,因此没有打开其他连接、语句或结果集。错误是

Operation not allowed after ResultSet closed
java.sql.SQLException: Operation not allowed after ResultSet closed
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
        at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:768)
        at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:7008)
        at equipmentinventoryimporter.Importer.sqlTable(Importer.java:219)
        at equipmentinventoryimporter.Importer.main(Importer.java:58)
功能是

private static void sqlTable(SQLTableJob sqltableJob) {
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            Connection connMySQL2 = null;
            Statement stntMySQL2 = null;
            try {
                connMySQL2 = DriverManager.getConnection(mysqlAddress, mysqlUsername, mysqlPassword);
                stntMySQL2 = connMySQL2.createStatement();
                //MySQL Transaction
                System.out.println("Starting " + sqltableJob.getMysqlTable() + " transaction");
                stntMySQL2.execute("START TRANSACTION");
                String insertQuery = "";
                try {
                    final String inactiveQuery = "UPDATE `" + sqltableJob.getMysqlSchema() + "`.`" + sqltableJob.getMysqlTable() + "` SET `active`=0";
                    stntMySQL2.executeUpdate(inactiveQuery);
                    final ResultSet rs2 = stntMySQL2.executeQuery(sqltableJob.getSQLSelectQuery());
                    int counter = 0;
                    while (rs2.next()) {
                        counter++;
                        final String mysqlSetClause = sqltableJob.getMysqlSetClause(rs2);
                        insertQuery = "INSERT INTO `" + sqltableJob.getMysqlSchema() + "`.`" + sqltableJob.getMysqlTable() + "` SET " +
                                mysqlSetClause +
                                " ON DUPLICATE KEY UPDATE " +
                                mysqlSetClause;
                        stntMySQL2.executeUpdate(insertQuery);
                        if (counter % 5000 == 0) {
                            System.out.println("Processed " + counter + " rows.");
                        }
                    }
                    rs2.close();

                    if (!sqltableJob.isKeepInactives()) {
                        final String deleteQuery = "DELETE FROM `" + sqltableJob.getMysqlSchema() + "`.`" + sqltableJob.getMysqlTable() + "`" +
                                "WHERE `active`=0";
                        stntMySQL2.executeUpdate(deleteQuery);
                    }

                    stntMySQL2.execute("COMMIT");//last line of try block
                    System.out.println("Committed " + sqltableJob.getMysqlTable() + " transaction");
                } catch (Exception ex) {
                    System.out.println(ex.getMessage());
                    ex.printStackTrace();
                    System.out.println("Transaction level exception thrown.");
                    System.out.println(insertQuery);
                    stntMySQL2.execute("ROLLBACK");
                    System.out.println("MySQL query rolled back.");
                }
            //Another MySQL Transaction goes here
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
                ex.printStackTrace();
                System.out.println("Connection level exception thrown.");
            } finally {
                if (stntMySQL2 != null) {
                    try {
                        stntMySQL2.close();
                    } catch (Exception ex) {
                    }
                }
                if (connMySQL2 != null) {
                    try {
                        connMySQL2.close();
                    } catch (Exception ex) {
                    }
                }
            }
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            ex.printStackTrace();
            System.out.println("Program level exception thrown.");
        }
    }
SQLTableJob是

package equipmentinventoryimporter;

import java.sql.ResultSet;
import java.sql.SQLException;
/**
 *
 * @author jmgreen
 */
public interface SQLTableJob {

    public String getMysqlSchema();

    public String getMysqlTable();

    public String getSQLSelectQuery();

    public String getMysqlSetClause(ResultSet rs) throws SQLException;

    public boolean isKeepInactives();
}
并且引用的特定SQLTableJob是

public class SQLTableJob10I implements SQLTableJob{

public boolean isKeepInactives() {
        return true;
    }

    public String getMysqlSchema() {
        return "Temp_Equipment_Inventory";
    }

    public String getMysqlTable() {
        return "PC_Combined";
    }

    public String getSQLSelectQuery() {
        final String sqlSelectQuery = "SELECT *" +
                " FROM Temp_Equipment_Inventory.PC_Table10i";
        return sqlSelectQuery;
    }

    public String getMysqlSetClause(ResultSet rs) throws SQLException {
        final String mysqlSetClause =
                "`Account_No`=" + Importer.sqlChar(rs.getString("Account_No")) +
                ",`Inventory_No`=" + Importer.sqlChar(rs.getString("Inventory_No")) +
                ",`Building_No`=" + Importer.sqlChar(rs.getString("Building_No")) +
                ",`Location`=" + Importer.sqlChar(rs.getString("Location")) +
                ",`FYYR_No`=" + Importer.sqlChar(rs.getString("FYYR_No")) +
                ",`Cost`=" + Importer.sqlChar(rs.getString("Cost")) +
                ",`Name`=" + Importer.sqlChar(rs.getString("Name")) +
                ",`Desc1`= ''" +
                ",`Desc2`= ''" +
                ",`Desc3`= ''" +
                ",`CDCATY`=" + Importer.sqlChar(rs.getString("CDCATY")) +
                ",`CDSRCE`=" + Importer.sqlChar(rs.getString("CDSRCE")) +
                ",`FLDCAL`=" + Importer.sqlChar(rs.getString("FLDCAL")) +
                ",`CDACQN`=" + Importer.sqlChar(rs.getString("CDACQN")) +
                ",`FLOWNR`=" + Importer.sqlChar(rs.getString("FLOWNR")) +
                ",`FLSHAR`=" + Importer.sqlChar(rs.getString("FLSHAR")) +
                ",`CDDELT`=" + Importer.sqlChar(rs.getString("CDDELT")) +
                ",`CNYTDT`=" + Importer.sqlChar(rs.getString("CNYTDT")) +
                ",`NOPURO`=" + Importer.sqlChar(rs.getString("NOPURO")) +
                ",`NOPIMO`=" + Importer.sqlChar(rs.getString("NOPIMO")) +
                ",`CDPREI`=" + Importer.sqlChar(rs.getString("CDPREI")) +
                ",`Original_Amount`=" + Importer.sqlChar(rs.getString("Original_Amount")) +
                ",`Serial_Code`=" + Importer.sqlChar(rs.getString("Serial_Code")) +
                ",`CDCOMP`=" + Importer.sqlChar(rs.getString("CDCOMP")) +
                ",`NOCHECK`=" + Importer.sqlChar(rs.getString("NOCHECK")) +
                ",`CDCOMM`=" + Importer.sqlChar(rs.getString("CDCOMM")) +
                ",`Last_Update`=" + Importer.sqlDate(rs.getString("Last_Update")) +
                ",`CDDEPT`=" + Importer.sqlChar(rs.getString("CDDEPT")) +
                ",`Room_No`=" + Importer.sqlChar(rs.getString("Room_No")) +
                ",`Date_Scanned`=" + Importer.sqlDate(rs.getString("Date_Scanned")) +
                ",`Date_Acquired`=" + Importer.sqlDate(rs.getString("Date_Acquired")) +
                ",`Manufacturer_Name`=" + Importer.sqlChar(rs.getString("Manufacturer_Name")) +
                ",`Expiry_Date`=" + Importer.sqlDate(rs.getString("Expiry_Date")) +
                ",`Active`='1'";
        return mysqlSetClause;
    }
}
从:

当生成它的
语句
对象关闭、重新执行或用于从多个结果序列中检索下一个结果时,
ResultSet
对象将自动关闭

从您的代码:

                stntMySQL2.executeUpdate(inactiveQuery);
                final ResultSet rs2 = stntMySQL2.executeQuery(sqltableJob.getSQLSelectQuery());
                while (rs2.next()) {
                    ...
                    stntMySQL2.executeUpdate(insertQuery);
您正在循环内重新执行
stntMySQL2
。这会自动关闭
rs2

若要修复,请在循环内使用不同的语句对象。

来自:

当生成它的
语句
对象关闭、重新执行或用于从多个结果序列中检索下一个结果时,
ResultSet
对象将自动关闭

从您的代码:

                stntMySQL2.executeUpdate(inactiveQuery);
                final ResultSet rs2 = stntMySQL2.executeQuery(sqltableJob.getSQLSelectQuery());
                while (rs2.next()) {
                    ...
                    stntMySQL2.executeUpdate(insertQuery);
您正在循环内重新执行
stntMySQL2
。这会自动关闭
rs2


要解决,在循环中使用不同的语句对象。

能否提供文件SQLTableJob.java的内容?请检查请求编辑的原始post。能否提供文件SQLTableJob.java的内容?请检查请求编辑的原始post。还要注意,关闭
连接将自动关闭所有
语句
从中创建的实例。这不在JavaDoc中,但JDBC规范要求这样做。最近通过另一个问题发现了这一点。还要注意,关闭
连接
将自动关闭从该连接创建的所有
语句
实例。这不在JavaDoc中,但JDBC规范要求这样做。最近通过另一个问题发现了这一点。