昨天晚上晚上弄了一晚上,总是出现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();
}
}

解决方案 »

  1.   

    注:里边的DataBase是我包装好的,没问题 
    问题就在你说的没问题这里
    把代码发出来再说
      

  2.   

    DataBase.query(sqlQuery);
    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,而在外面也没见有关闭,则很快程序就会把数据库资源耗光。
      

  3.   

    我已经在这个程序中用了很多次了,应该没问题
    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;
    }
    }
     
      

  4.   


    下面是异常代码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)

      

  5.   

    请你仔细看我7楼第一种情况的说明。----------
    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
      

  6.   


    谢谢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();