【问题标题】:ResultSet not open although i have only one at a time结果集未打开,尽管我一次只有一个
【发布时间】:2016-07-08 23:21:49
【问题描述】:

我知道之前有人就这个问题提出过很多问题,但对于这种情况,我找不到答案。

这是我的代码:

private Collection<Coupon> getCouponsMain(Company company, String filters) throws DAOException
{
    String sql = null;
    if (filters != null)
    {
        sql = "SELECT couponsystem.coupon.* FROM couponsystem.company_coupon LEFT JOIN couponsystem.coupon ON "
            + "couponsystem.company_coupon.COUPON_ID = couponsystem.coupon.ID WHERE couponsystem.company_coupon.COMP_ID = ? AND ?";
    }
    else
    {       
         sql = "SELECT couponsystem.coupon.* FROM couponsystem.company_coupon LEFT JOIN couponsystem.coupon ON "
            + "couponsystem.company_coupon.COUPON_ID = couponsystem.coupon.ID WHERE couponsystem.company_coupon.COMP_ID = ?";           
    }

    try (Connection con = pool.OpenConnection(); PreparedStatement preparedStatement = con.prepareStatement(sql);)
    {   
        // query command

        preparedStatement.setLong(1, company.getId());
        if (filters != null)
        {
            preparedStatement.setString(2, filters);
        }

        ResultSet rs = preparedStatement.executeQuery();

        if (rs.next())
        {
            CouponDBDAO couponDao = new CouponDBDAO();  
            rs.previous();
            return couponDao.BuildCoupons(rs);
        }
        else
        {
            return null;
        }
    }
    catch (SQLException | NullPointerException e)
    {
        throw new DAOException("Failed to retrieve data for all coupons" + e.getMessage());
    }
}

我认为查询本身不是这里的重要问题,但是,一旦我将 next() 用于 ResultSet,我就会收到错误:

java.sql.SQLException: ResultSet 关闭后不允许操作"

这通常发生在同一语句使用两个 rs 时,这次不是这样。

由于之前的方法有很多问题和 BuildCoupons(rs) 问题,这部分也因为同样的原因不能正常工作:

@Override
public Company getCompany(long id) throws DAOException
{
    String sql = "SELECT * FROM couponsystem.company WHERE ID = ?";
    try (Connection con = pool.OpenConnection(); PreparedStatement preparedStatement = con.prepareStatement(sql);)
    {   
        // query command

        preparedStatement.setLong(1, id);

        // query execution
        ResultSet rs = preparedStatement.executeQuery();

        Company comp = new Company();
        if (rs.next())
        {
            //Fill customer object from Customer table              
            comp.setId(rs.getLong("ID"));
            comp.setCompName(rs.getString("COMP_NAME"));
            comp.setPassword(rs.getString("PASSWORD"));
            comp.setEmail(rs.getString("EMAIL"));
            comp.setCoupons(comp.getCoupons());
        }   
        else
        {
            comp = null;
        }

        return comp;
    }
    catch (SQLException e)
    {
        throw new DAOException("Failed to retrieve data for customer id: " + id);
    }
}

顺便说一句 - 使用 MySQL 并且插入、更新和删除查询工作正常,因此与 db 的连接没有问题

另一个更新 - 一旦我将它替换为常规语句,它就可以工作了,但是我当然失去了准备好的语句的所有优点

就像我说的,我创建新代码是为了隔离大程序 这是代码:

public class testState 
{
    public static void main(String[] args) throws SQLException
    {
            DBDAO pool = DBDAO.getInstance();

            String sql = "SELECT ID FROM couponsystem.company WHERE COMP_NAME = ? AND PASSWORD = ?";
            String compName = "t";
            String password = "t";

            pool.CreatePool();
            Connection con = pool.OpenConnection(); 
            PreparedStatement preparedStatement = con.prepareStatement(sql);

                preparedStatement.setString(1, compName);
                preparedStatement.setString(2, password);
preparedStatement.executeQuery();
                ResultSet rs = preparedStatement.executeQuery();

                System.out.println("rs status: " + rs.isClosed());
                if (rs.next())
                {
                    System.out.println("log-in was successfuly performed");
                    System.out.println(rs.getLong(1));
                    System.out.println("hjhjh");
                }
                else
                {
                    System.out.println("-1");
                }

            rs.close();
            preparedStatement.close();
            con.close();
            pool.CloseConnection();
    }
}

【问题讨论】:

  • 1) 哪一行抛出异常? 2) 你为什么打电话给rs.previous()? 3) 你知道rs.previous() 会像rs.next() 一样返回一个布尔值,对吧?
  • 这一行:if (rs.next()) 上一条的原因是:我有一个函数以while (rs.next())开头,我需要返回一行
  • @OP 此异常不是使用两个结果集引起的。它是由于在它之后使用了一个结果集,或者它的语句,或者它的连接已经关闭。在我看来,这不是真正的代码。注意你不能用 ? 添加整个 WHERE 子句符号,所以这种技术无论如何都行不通。你需要重新考虑。
  • 请发布堆栈跟踪。我不相信上述问题的存在。
  • 你能发布最短的代码来演示这个问题吗? {MCVE] 最好。例如,如果您“认为查询本身不是重要问题”,请使用最简单的查询来演示问题。顺便说一句:在许多情况下,准备 MCVE 可以查明问题并帮助您解决问题。

标签: java jdbc resultset


【解决方案1】:

问题解决了, 这就是问题所在:

sql = "SELECT couponsystem.coupon.* FROM couponsystem.company_coupon LEFT JOIN couponsystem.coupon ON " + "couponsystem.company_coupon.COUPON_ID = couponsystem.coupon.ID WHERE couponsystem.company_coupon.COMP_ID = ? AND ?";

第二个?是非法的,但异常是 ResultSet 关闭而不是查询问题

【讨论】:

    【解决方案2】:

    问题是您试图返回结果集中的上一条记录,这是不可能的。

    了解可滚动结果集并使其不敏感,一旦使用它,您可以使用 rs.previous() 返回上一个记录

    ResultSet.TYPE_SCROLL_INSENSITIVE

    【讨论】:

    • 这不会导致ResultSet closed异常,并且无论如何在previous()调用中不会出现问题。
    猜你喜欢
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 2017-11-21
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    相关资源
    最近更新 更多