【问题标题】:Can't figure out why sqlite query isn't returning the right result无法弄清楚为什么 sqlite 查询没有返回正确的结果
【发布时间】:2013-05-14 23:04:35
【问题描述】:

我有这个 sqlite 数据库,我可以运行查询“从条形码中选择 *,其中条形码 ='CFMS-ZUFH-WRVY-EXAA' 并获得单行返回。但在我的 Java 应用程序中,当我运行几乎相同时sql,它返回一个空结果集。变量last、email等是JTextFields,尽管问题在它们之前。if语句甚至不执行,如果我在它之前运行rs.next()并设置if(true)我收到一条错误消息,提示 ResultSet 已关闭。

try {
    db.dbopen(config.getdbfolder(),config.getdbname()); 
    // barcode-barcode.replaceAll("\\s","");
    ResultSet rs=db.query("select * from barcode where barcode=?",barcode);

    if (rs.next()) {
        first.setText(rs.getString("first_name"));
        System.out.println(rs.getString("first_name"));
        last.setText(rs.getString("last_name"));
        email.setText(rs.getString("email"));
        phone.setText(rs.getString("phone"));
        subject.setSelectedItem(rs.getString("subject"));
        Boolean selected;
        if (rs.getString("baronly").equals("false")) selected=false;
        else selected=true;
        barcodebox.setSelected(selected);   
        update=true;

    } 
    db.conn.close();

} catch ( SQLException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

这是方法查询。

public ResultSet query(String sql, String barcode) throws SQLException {
    // TODO Auto-generated method stub
    PreparedStatement prep =conn.prepareStatement(sql);
    prep.setString(1, barcode);

    ResultSet rs= prep.executeQuery();  
    prep.close();
    return rs;
}

【问题讨论】:

  • if (rs.next()) { 不应该是while (rs.next()) {吗?
  • @Smit 不,不必如此。 rs.next() 只是检查是否返回了任何行
  • 不,只有一个结果
  • @Codeguy007 光标最初指向第一行之前。所以执行 next() 会检查它是否返回了任何结果
  • @TemporaryNickName 不开​​玩笑。那不是我的问题。

标签: java sqlite


【解决方案1】:

在您的query 方法中,您在返回ResultSet 之前关闭PreparedStatement。根据Javadocs for close

注意:当一个Statement对象关闭时,它当前的ResultSet对象, 如果存在,也关闭。

不要在query中关闭你的PreparedStatement,在使用ResultSet后关闭它。我将删除 query 方法并将其代码与您的其余代码内联,这样您在完成 ResultSet 后仍然可以关闭对 PreparedStatement 的引用。

正如@Reimeus 已经提到的,将replaceAll 的结果分配回barcode

【讨论】:

  • 是的,它不是那样工作的。如果我在查询中注释掉 prep.close() ,则以前使用该函数查询将失败。我将尝试用内联代码替换查询,看看我是否有更好的运气。
  • 我没有说“根本不要关闭它”。您必须重新排列代码,以便在处理完 ResultSet 后关闭它。
  • 没关系,我改变了一些东西,扭转了之前使用查询的逻辑,所以尽管查询没有返回任何内容,它仍然可以工作。我将整个代码移入内联,现在可以正常工作了。
【解决方案2】:

您想要的条形码可能仍然有空格。赋值给replaceAll的结果:

barcode = barcode.replaceAll("\\s","");

【讨论】:

  • 拍了,没看到那个XD
  • 你不必担心那条线。条形码是最终的,所以无论如何我都无法改变它的价值。我只是想看看变量中的空格是否有问题,但这不是问题。
【解决方案3】:

所以这是来自@Reimeus @rgettman 的最终答案。

        try {
            db.dbopen(config.getdbfolder(),config.getdbname()); 
            //you need to set this replaceAll return value to original variable
            barcode = barcode.replaceAll("\\s","");

            //make prep statement here in order to close it in the finally block
            PreparedStatement prep =conn.prepareStatement("select * from barcode where barcode=?");

            //modify query function to accept prepared statement instead of a string
            ResultSet rs=db.query(prep ,barcode);

            if (rs.next()) {
                first.setText(rs.getString("first_name"));
                System.out.println(rs.getString("first_name"));
                last.setText(rs.getString("last_name"));
                email.setText(rs.getString("email"));
                phone.setText(rs.getString("phone"));
                subject.setSelectedItem(rs.getString("subject"));
                Boolean selected;
                if (rs.getString("baronly").equals("false")) selected=false;
                else selected=true;
                barcodebox.setSelected(selected);   
                update=true;

            } 
            db.conn.close();

        } catch ( SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
         //finally you close prepared statement. note that closing prep also closes 
//resultset and closing connection won't clean up resultset nor prep according to most of 
//stackoverflow answers. However, it is recommended to close both resultset and prepared 
//statement explicitly
         prep.close();
         rs.close();
       }

如果您的数据库表具有匹配 where 子句条件的正确值,这必须有效。请在测试运行时仔细检查您的查询是否成功执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    • 2015-04-23
    相关资源
    最近更新 更多