ResultSet已关闭

时间:2014-08-17 17:44:05

标签: java jdbc resultset

以下是我的表定义:

create Table alarms(
         alarmId int primary key identity(1,1),
         alarmDate varchar(50) not null,
         alarmText varchar(50) not null,
         alarmStatus varchar(10) Check (alarmStatus in(-1, 0, 1)) Default 0
         );

其次,这是我正在使用的一些方法:

public void restartDatabase(){
try{
        Class.forName(Settings.getDatabaseDriver());
        connection = DriverManager.getConnection( Settings.getJdbcUrl() );
        statement = connection.createStatement();
    }
    catch(Exception e){ 
        e.printStackTrace(); 
    }
}


public ResultSet executeQuery(String query){
ResultSet result = null;
try {
    result = statement.executeQuery(query); 
   } catch (SQLException e) {
    e.printStackTrace();
   }
return result;          
}

public void closeDatabase() {
try {
  if ((statement != null) && (connection != null)) {    
      statement.close();
      connection.close();
  }
} catch (Exception e) {
    e.printStackTrace();
}
 }

我想要做的是从日期等于给定日期的表中获取所有alarmId,然后针对每个alarmId获取我想要将其状态更新为给定状态:

public static void updateAlarmStatus(int status) {
    ResultSet rs = null;
    database.restartDatabase();
    try {
        rs = database
                .executeQuery("Select alarmId from alarms where alarmDate = '"
                        + Alarm.getFormattedDateTime(DateFormat.FULL,
                                DateFormat.SHORT) + "'");
        while (rs.next()) {
            database.executeUpdate("update alarms set alarmStatus = '"+status+"' where alarmId = '"+rs.getString("alarmId")+"'");
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        database.closeDatabase();
    }
}

但它会生成结果集已关闭的错误。 我Goggled它并且知道当我们尝试在其中执行另一个查询时,结果集会自动关闭 它需要重新启动连接。 我尝试调用restartDatabase()方法,该方法正在创建新连接但仍然遇到相同的错误。

2 个答案:

答案 0 :(得分:1)

我猜测executeUpdate在查询使用时为其Statement使用相同的实例变量。当您创建一个新的Statement并将其分配给变量时,没有任何东西指的是旧的,因此它会被松散并变成垃圾收集。在垃圾收集期间,调用语句的终结器,关闭它。关闭语句会使它创建的ResultSet也关闭。

您不应该在不同的查询和更新之间共享这些Statement变量。该语句应该是局部变量,而不是对象实例的成员。

此外,结果集应始终为局部变量,不应将它们传递到创建它们的方法之外。 resultSet是对游标的引用,它实际上不包含任何数据。始终从resultSet读取代码并使用结果填充一些数据结构,然后返回数据结构。

答案 1 :(得分:0)

您还可以一次选择并更改所有alarmIds:

rs = database.
    executeQuery("Select group_concat(distinct alarmId) as alarmIds from alarms group by alarmDate having alarmDate = '"
                        + Alarm.getFormattedDateTime(DateFormat.FULL,
                                DateFormat.SHORT) + "'");
while (rs.next()) { // there will be only one result
    database.executeUpdate("update alarms set alarmStatus = '"+status+"' where alarmId in ("+rs.getString("alarmIds")+")");
}