Java 结果集已关闭
以下是我的表定义:Java 结果集已关闭,java,jdbc,resultset,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 );
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,其中date等于给定日期,然后针对每个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();
}
}
但它会产生结果集关闭的错误。
我目不转睛地看着它,发现当我们试图在其中执行另一个查询时,结果集会自动关闭
它需要重新启动连接。
我尝试调用正在创建新连接的restartDatabase()方法,但仍然收到相同的错误。您还可以一次选择并更改所有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")+")");
}
我猜executeUpdate对其语句使用的实例变量与查询使用的实例变量相同。当您创建一个新语句并将其分配给变量时,没有任何内容引用旧语句,因此它会被截断并接受垃圾收集。在垃圾收集期间,将调用语句的终结器,并将其关闭。关闭语句会使它创建的结果集也关闭 您不应该在不同的查询和更新之间共享这些语句变量。该语句应该是局部变量,而不是对象实例的成员
此外,结果集应该始终是局部变量,它们不应该被传递到创建它们的方法之外。resultSet是对游标的引用,它实际上不包含任何数据。始终从resultSet读取代码,并用结果填充某些数据结构,然后返回数据结构
database.executeUpdate()
是否使用与executeQuery()方法相同的语句
实例?对此,您也不需要两个语句。据我所知,一个简单的更新报警设置alarmStatus=1,其中alarmDate='2014-08-17'代码>将执行相同的操作。同时也要研究准备好的陈述。您对SQL注入非常开放。最后(但同样重要):不要在VARCHAR
列中存储日期,只是不要。我认为您已将connection和statement声明为实例变量,并且在executeUpdate发生之前语句会在某个地方关闭。您不应该像这样传递connection、statement或ResultSet。要重新启动连接,不需要重新加载驱动程序类。一旦重新连接,就必须重新运行查询。最后,代码中似乎还有一些其他问题。我建议你找一本关于JDBC的教程,或者改用ORM工具。有什么问题吗?你说的“要重新启动连接,你不需要重新加载驱动程序类。一旦重新连接,你就必须重新运行你的查询”是什么意思?MySQL函数将某个字段的值聚合为逗号分隔的字符串只做了一个小小的更改,以防同一日期有重复的alarmId值谢谢,我现在了解了所有内容,除了您的一些行:resultSet是对光标的引用,它实际上不包含任何数据。始终从resultSet读取代码,并用结果填充某些数据结构,然后返回数据结构。