【问题标题】:JDBC returns an empty ResultSet (rs.isBeforeFirst() == true) although the table isn't empty尽管表不为空,但 JDBC 返回一个空的 ResultSet (rs.isBeforeFirst() == true)
【发布时间】:2014-10-12 11:23:58
【问题描述】:

我正在尝试为我的 Web 服务完成数据库访问方法。服务和数据库访问方法适用于数据库中的所有其他表,但这一特定方法不能。当我查询数据库时,ResultSet 总是返回空(意思是isBeforeFirst() == true)。

经过多次尝试,我将查询缩减为一个简单的SELECT * FROM VIDEOS,以查看问题是否是我输入的数据与我在查询中使用的数据之间存在一些差异,但即使是这个简单的查询也可以选择表中的所有项目没有返回任何结果。

这是我用来从数据库中提取信息的方法:

public static Object[] getVideo(String phonenum, String timeStamp)
{
    Connection c = null;
    Statement stmt = null;
    Object[] result = null;
    try
    {
        Class.forName("org.sqlite.JDBC");
        c = DriverManager.getConnection("jdbc:sqlite:lineappDB.db");
        c.setAutoCommit(false);
        System.out.println("Opened database successfully");
        stmt = c.createStatement();
        String query = String.format("SELECT * FROM VIDEOS");
        ResultSet rs = stmt.executeQuery(query);

        // If no data was found
        if (rs.isBeforeFirst())
        {
            rs.close();
            stmt.close();
            c.close();
            return null;
        } else
        {
            result = new Object[6];
            while (rs.next())
            {
                result[0] = rs.getInt(1);
                result[1] = rs.getString(2);
                result[2] = rs.getString(3);
                result[3] = rs.getString(4);
                result[4] = rs.getString(5);
                result[5] = rs.getInt(6);
            }
        }
        rs.close();
        stmt.close();
        c.close();
    } catch (Exception e)
    {
        try
        {
            if (!c.isClosed())
            {
                c.commit();
                c.close();
            }
        } catch (Exception ex)
        {
            System.err.println(ex.getClass().getName() + ": " + ex.getMessage());
            return null;
        }
        System.err.println(e.getClass().getName() + ": " + e.getMessage());
        return null;
    }
    System.out.println(String.format("Succesfully pulled from DB - %s %s", result[1], result[2]));
    return result;
}

任何帮助将不胜感激。

澄清编辑: 该方法是 Web 服务的一部分,该服务从数据库中提取特定视频的路径,以发送到客户端。视频由客户端上传,然后存储在文件系统中,其路径存储在数据库本身中。

一旦我看到数据库正常工作,我会将SELECT * FROM VIDEOS 替换为SELECT * FROM VIDEOS WHERE PHONENUM = '%s' AND DATETIME = '%s'", phonenum, timeStamp,以便查询提取我需要的确切项目。

【问题讨论】:

  • 我会将所有.close() 命令放入finally 块中
  • @David 谢谢你的建议,我会这样做的。
  • @David 当我将我的.close() 命令放在finally 块中时,eclipse 大喊我没有处理异常。所以我需要再次使用双 try catch 块。你能举个正确的例子吗?
  • @1CodeRed 实际上,在这个时代,为什么不使用try-with-resource idiom

标签: java sql database sqlite jdbc


【解决方案1】:

isBeforeFirst() 返回true,如果下一次调用next() 会将光标放在ResultSet 的第一行。换句话说,任何有数据的成功查询,一旦执行,都会产生一个ResultSetisBeforeFirst()返回true

只需从您的代码中删除该块,并让rs.next() 循环处理可能为空的ResultSets:

try
{
    Class.forName("org.sqlite.JDBC");
    c = DriverManager.getConnection("jdbc:sqlite:lineappDB.db");
    c.setAutoCommit(false);
    System.out.println("Opened database successfully");
    stmt = c.createStatement();
    String query = String.format("SELECT * FROM VIDEOS");

    result = new Object[6];
    ResultSet rs = stmt.executeQuery(query);
    while (rs.next())
    {
        result[0] = rs.getInt(1);
        result[1] = rs.getString(2);
        result[2] = rs.getString(3);
        result[3] = rs.getString(4);
        result[4] = rs.getString(5);
        result[5] = rs.getInt(6);
    }
} 
/* catch and finally snipped for clarity of the answer */

【讨论】:

  • 非常简单的解决方案,非常感谢。我很惊讶我没有在其他桌子上遇到这个问题。多么愚蠢的错误:)
  • (cc: @1CodeRed ) +1 用于解释 .isBeforeFirst() 的真正含义。事实上,空 ResultSet 的测试是 .isBeforeFirst() 返回 false,而不是 true(正如 OP 所认为的)。
  • 嘿 Mureinik,Yuval 假设使用 if (!rs.isBeforeFirst()) 来检查结果是否设置为空。如果它不为空,那么他可以进一步处理并使用结果集。
【解决方案2】:

使用 if (!rs.isBeforeFirst()) 代替 if (rs.isBeforeFirst())。你的问题就解决了。

【讨论】:

    猜你喜欢
    • 2021-03-18
    • 1970-01-01
    • 2019-03-22
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    • 2017-12-01
    相关资源
    最近更新 更多