java 尽管表不为空,但 JDBC 返回一个空的 ResultSet (rs.isBeforeFirst() == true)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26324603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 09:42:37  来源:igfitidea点击:

JDBC returns an empty ResultSet (rs.isBeforeFirst() == true) although the table isn't empty

javasqldatabasesqlitejdbc

提问by Yuval

I am trying to complete a DB access method for my Web Service. The service and the DB access methods work fine for all other tables in the DB, but this one particular method does not. When I query the DB, the ResultSetalways returns empty (meaning isBeforeFirst() == true).

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

After many tries I cut my query to a simple SELECT * FROM VIDEOSto see if the problem is some difference between the data I entered and the data I use in my query, but even this simple query to select all items in the table didn't return any result.

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

This is the method I use to pull info from the DB:

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

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;
}

Any help will be very appreciated.

任何帮助将不胜感激。

CLARIFICATION EDIT: The method is part of a web service that pulls a path of a certain video from the DB, to be sent to a client. The videos are uploaded by clients and are then stored in the filesystem, and their paths are stored in the DB itself.

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

Once I see the DB works, I will replace SELECT * FROM VIDEOSwith SELECT * FROM VIDEOS WHERE PHONENUM = '%s' AND DATETIME = '%s'", phonenum, timeStampso that the query pulls the exact item I need.

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

回答by Mureinik

isBeforeFirst()returns trueif the next call to next()will put the cursor on the first row of the ResultSet. In other words, any successful query that has data, once executed, will produce a ResultSetwith isBeforeFirst()returning true.

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

Just remove that block from your code, and have the rs.next()loop deal with potentially empty ResultSets:

只需从您的代码中删除该块,并让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 */

回答by manohar e

Use if (!rs.isBeforeFirst()) instead of if (rs.isBeforeFirst()). your problem would be solved.

使用 if (!rs.isBeforeFirst()) 而不是 if (rs.isBeforeFirst())。你的问题就解决了。