以下是我的表定义:
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()方法,该方法正在创建新连接但仍然遇到相同的错误。
答案 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")+")");
}