昨天晚上晚上弄了一晚上,总是出现ResultSet is closed 这个异常,请大家看看怎么回事,错误出现的地方已经注释出来了
注:里边的DataBase是我包装好的,没问题
public void updateTable()
{
try {
String sqlQuery = "select 最近发放记录.工作证号码,部门名称,职工姓名,用品名称,用品单位.用品单位编码 as 用品单位 ,发放数量,发放周期,发放日期 from 最近发放记录,用品,发放规则,用品单位,职工信息,部门 ";
sqlQuery += "where 最近发放记录.工作证号码=职工信息.工作证号码 and 职工信息.部门编码=部门.部门编码 and 职工信息.工种编码=发放规则.工种编码 and 最近发放记录.用品编码=发放规则.用品编码 and 发放规则.用品单位编码=用品单位.用品单位编码 and 最近发放记录.用品编码=用品.用品编码 ";
System.out.println(sqlQuery);
Calendar currentTime = Calendar.getInstance();
int year = currentTime.get(Calendar.YEAR);
int month = currentTime.get(Calendar.MONTH)+1;
int day = currentTime.get(Calendar.DAY_OF_MONTH);
DataBase.query(sqlQuery);
ResultSet rs = DataBase.getResultSet();
ResultSetMetaData rsmd = rs.getMetaData();
Vector columnName = new Vector();
for (int i=1;i<=6; ++i)
columnName.add(rsmd.getColumnName(i));
Vector rowData = new Vector();
///////////////////////////////////////
/////////////////////////////////////////////////////
while (rs.next()) /////////////////////错误在这里
{
System.out.println(123);//测试用的,输出了7次,而用查询分析器查出了9行
Vector row = new Vector();
for (int i=1; i<=6; ++i)
row.add(rs.getString(i));
String cur = year+"-"+month+"-"+day;
String sqlUpdate = "update 最近发放记录 set 发放日期='"+cur+"' where 工作证号码='"+row.get(0)+"' and 用品编码=(select 用品编码 from 用品 where 用品名称='"+row.get(4)+"')";
String sqlInsert = "insert into 用品发放 values('"+row.get(0)+"','"+row.get(1)+"','"+row.get(2)+"','"+row.get(3)+"','"+row.get(4)+"',"+row.get(5)+",'"+cur+"')";
int ffzq = Integer.parseInt(rs.getString(7));
String ffDate = rs.getString(8);
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date(new SimpleDateFormat("yyyy-MM-dd").parse(ffDate).getTime()));
calendar.add(Calendar.DAY_OF_YEAR, ffzq);
if (calendar.get(Calendar.YEAR)==year && calendar.get(Calendar.MONTH)+1==month)
{
DataBase.update(sqlUpdate);
DataBase.update(sqlInsert);
rowData.add(row);
}
}
DefaultTableModel tableModel = new DefaultTableModel(rowData,columnName);
table.setModel(tableModel);
table.repaint();
} catch (SQLException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
注:里边的DataBase是我包装好的,没问题
public void updateTable()
{
try {
String sqlQuery = "select 最近发放记录.工作证号码,部门名称,职工姓名,用品名称,用品单位.用品单位编码 as 用品单位 ,发放数量,发放周期,发放日期 from 最近发放记录,用品,发放规则,用品单位,职工信息,部门 ";
sqlQuery += "where 最近发放记录.工作证号码=职工信息.工作证号码 and 职工信息.部门编码=部门.部门编码 and 职工信息.工种编码=发放规则.工种编码 and 最近发放记录.用品编码=发放规则.用品编码 and 发放规则.用品单位编码=用品单位.用品单位编码 and 最近发放记录.用品编码=用品.用品编码 ";
System.out.println(sqlQuery);
Calendar currentTime = Calendar.getInstance();
int year = currentTime.get(Calendar.YEAR);
int month = currentTime.get(Calendar.MONTH)+1;
int day = currentTime.get(Calendar.DAY_OF_MONTH);
DataBase.query(sqlQuery);
ResultSet rs = DataBase.getResultSet();
ResultSetMetaData rsmd = rs.getMetaData();
Vector columnName = new Vector();
for (int i=1;i<=6; ++i)
columnName.add(rsmd.getColumnName(i));
Vector rowData = new Vector();
///////////////////////////////////////
/////////////////////////////////////////////////////
while (rs.next()) /////////////////////错误在这里
{
System.out.println(123);//测试用的,输出了7次,而用查询分析器查出了9行
Vector row = new Vector();
for (int i=1; i<=6; ++i)
row.add(rs.getString(i));
String cur = year+"-"+month+"-"+day;
String sqlUpdate = "update 最近发放记录 set 发放日期='"+cur+"' where 工作证号码='"+row.get(0)+"' and 用品编码=(select 用品编码 from 用品 where 用品名称='"+row.get(4)+"')";
String sqlInsert = "insert into 用品发放 values('"+row.get(0)+"','"+row.get(1)+"','"+row.get(2)+"','"+row.get(3)+"','"+row.get(4)+"',"+row.get(5)+",'"+cur+"')";
int ffzq = Integer.parseInt(rs.getString(7));
String ffDate = rs.getString(8);
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date(new SimpleDateFormat("yyyy-MM-dd").parse(ffDate).getTime()));
calendar.add(Calendar.DAY_OF_YEAR, ffzq);
if (calendar.get(Calendar.YEAR)==year && calendar.get(Calendar.MONTH)+1==month)
{
DataBase.update(sqlUpdate);
DataBase.update(sqlInsert);
rowData.add(row);
}
}
DefaultTableModel tableModel = new DefaultTableModel(rowData,columnName);
table.setModel(tableModel);
table.repaint();
} catch (SQLException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
解决方案 »
- Class.forName实例化类没有
- 求与group by有关的SQL,100分相送
- 小弟有个小问题搞不懂,请高手指点一下,感激万分!
- 请问怎么过滤树节点,注意是过滤,不是查找
- 有没有这样的实现?
- 求教Jtree的使用方法
- 请问如何得到调用该类的对象
- 请帮个忙!谢谢!
- 刚看到一篇所谓的精华文章,关于package和classpath的,在下觉得有话要说,来着有分!
- 在浏览器中用 ctrl-f 可以吊出页面搜索的功能,怎样用javascript的函数把它也吊出来呀?
- 快速排序,简洁到难以置信!!
- 在linux里面的crontab运行一个java程序,java里面system.out.print输出到哪里去了
问题就在你说的没问题这里
把代码发出来再说
ResultSet rs = DataBase.getResultSet();如果贴出getResultSet的代码,应该很容易看出问题。现在我只能猜测如下:
第一种情况:
getResultSet()有可能被多个线程并发调用,而在这个方法内,没有为每个线程提供一个新的Statement(线程不安全),
这样后来的线程与前一个线程使用同一个Statement上执行查询,导致前一个线程的ResultSet被关闭
(这是JDBC的特性,一个Statement只能维持一个ResultSet为打开状态,后面的覆盖前面的)第二种情况:
getResultSet()这个方法的伪代码类似如下逻辑:
----------
Statement stat=connection.createStatement();
ResultSet rs=stat.executeQuery(sql);
stat.close();
return rs;
------------
如果statement被关闭,则ResultSet肯定被关闭,如果说你在方法内部不关闭Statement,而在外面也没见有关闭,则很快程序就会把数据库资源耗光。
package tool;import java.sql.*;public class DataBase
{
private static ResultSet rs; //数据库查询结果集
private static Statement stmt;//数据库语句执行对象
private static Connection con;//数据库连接对象
/////////////获得rs
public static ResultSet getResultSet(){return rs;}
////////////指定数据库驱动程序
public static boolean dataBaseRegist()
{
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
}
/////////////连接数据库
public static boolean dataBaseConnection()
{
String url = "jdbc:odbc:lbconn";
String user = "sa";
String password = "";
try {
con = DriverManager.getConnection(url, user, password);
stmt = con.createStatement();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 获得PreparedStatement
* @param sql
* @return
*/
public static PreparedStatement getPreparedStatement(String sql)
{
PreparedStatement pstmd = null;
try {
pstmd = con.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return pstmd;
}
////////////////////执行SQL语句
//更新
public static boolean update(String sql)
{
try {
stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
return false;
}
return true;
}
//查询
public static boolean query(String sql)
{
try {
rs = stmt.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
return false;
}
return true;
}
}
下面是异常代码java.sql.SQLException: ResultSet is closed
at sun.jdbc.odbc.JdbcOdbcResultSet.checkOpen(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcResultSet.next(Unknown Source)
at 用品发放.FfDataObtain.updateTable(FfDataObtain.java:89)
at 用品发放.FfDataObtain.<init>(FfDataObtain.java:64)
at login.MainMenu.actionPerformed(MainMenu.java:180)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
while (rs.next()) /////////////////////错误在这里
{
System.out.println(123);//测试用的,输出了7次,而用查询分析器查出了9行
Vector row = new Vector();
for (int i=1; i<=6; ++i)
//这中间的代码被我简化掉了
if (calendar.get(Calendar.YEAR)==year && calendar.get(Calendar.MONTH)+1==month)
{
DataBase.update(sqlUpdate);
DataBase.update(sqlInsert); rowData.add(row);
}
} ---------
上面标红的地方就是问题所在。
DataBase类只有一个statement,用来执行所有的query和update,而你在这个循环中还在使用上一次Query的ResultSet,
却有调用了DataBase.update方法,又使用了打开当前ResultSet的statement,当然会导致当前ResultSet关闭。你的DataBase类只有一个静态的statment
谢谢Jinxfei,问题解决了,我把过程写下来,供那些和我一样遇到这样问题的参考我先将DataBase.update(sqlUpdate);
DataBase.update(sqlInsert);
rowData.add(row);改为Connection con = DataBase.getConection();
Statement stmt = con.createStatement();
stmt.executeUpdate(sqlUpdate);
stmt.executeUpdate(sqlInsert);
stmt.close();
但是却又出现了“连接占线导致另一个 hstmt”这个异常
于是我又到网上查了一下,原来一个Connection对象创建的Statement对象在工作时只能有一个处于打开状态,其他的都必须close();
而我的程序中恰巧就有两个被同一个Connection创建而又同时处于打开状态的Statement对象
改成如下就没问题了Connection con = null;
Statement stmt = null;
try {
con = DriverManager.getConnection("jdbc:odbc:lbconn", "sa", "");
stmt = con.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
stmt.executeUpdate(sqlUpdate);
stmt.executeUpdate(sqlInsert);
rowData.add(row);
stmt.close();
con.close();