下面是我的Table Definition:
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();
}
}
但是它生成Result Set is Closed的错误。我用谷歌搜索了一下,发现当我们试图在其中执行另一个查询时,结果集会自动关闭它需要重新启动连接。我尝试调用restartDatabase()方法,正在创建新的连接,但仍然得到相同的错误。
我猜executeUpdate使用与查询使用的语句相同的实例变量。当您创建一个新的语句并将其赋值给变量时,没有任何东西指向旧的语句,因此它被切断并成为垃圾收集的对象。在垃圾收集期间,调用语句的终结器并关闭它。关闭语句使它创建的ResultSet也关闭。
你不应该在不同的查询和更新之间共享这些语句变量。语句应该是一个局部变量,而不是对象实例的成员。
同样,结果集应该始终是局部变量,它们不应该被传递到创建它们的方法之外。resultSet是对游标的引用,它实际上不包含任何数据。始终从resultSet中读取代码,并用结果填充一些数据结构,然后返回该数据结构。
您也可以一次选择和更改所有的alarmid:
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")+")");
}