ResultSet getFetchSize() 似乎不起作用?

Posted

技术标签:

【中文标题】ResultSet getFetchSize() 似乎不起作用?【英文标题】:ResultSet getFetchSize() doesn't seem to work? 【发布时间】:2013-01-11 10:33:51 【问题描述】:

我在使用 getFetchSize() 函数时遇到问题。

我只需要知道 SQL 查询是否返回了零行。

我试过这个简单的说法:

if (rs.getFetchSize()==0)
    System.out.println("HEADLINE");

其中rs 属于ResultSet 类型。上面的代码似乎不起作用。无论rs 是否为空,它都会打印消息。

我检查了 SQL 查询本身,当存在行时它正确返回了非空结果。

关于如何确定查询是否返回 0 行的任何想法? 我用谷歌搜索了它,找不到任何答案。

【问题讨论】:

【参考方案1】:

ResultSet.getFetchSize() 不返回结果数!来自here:

标准 JDBC 还允许您指定获取的行数 每个数据库往返一次查询,并引用此编号 以作为提取大小

您可以遍历结果集,如果没有任何条目,则可以确定没有结果。为什么你不能立即得到结果大小?因为数据库正在向您返回一个指向其结果的指针,并且它依赖于您对其进行迭代(每行返回到服务器)。

【讨论】:

当我在我的 sql 中运行一个 sql 查询时,我总是得到一个 MSG“X 行返回”。 ResultSet 中没有可以为我提供这些信息的函数吗? @ronnjack 不,因为(通常)事先不知道,但只有在检索到所有行之后(这发生在您的查询工具中) oki,如果我只需要知道是否返回了 0 行怎么办?我有一个 while 循环,它使用 while(rs.next()); 移动结果。如果 RS 为空,我想在循环之后放置一个 if 语句以打印一个 msg。你建议我怎么做? @ronnjack - 只是循环,如果你什么也没得到,那么你的结果集是空的。或者调用 ResultSet.next() 如果这没有给你任何结果,那么你的集合是空的 thx,我用 if (!rs.first()) 检查 rs 是否为空,它就像一个魅力【参考方案2】:

提取大小是每次往返中应从数据库中检索的行数。它与返回的行数无关。

你应该做的是调用 rs.next() - 如果你的查询没有返回任何行,它将返回 false。

【讨论】:

我对 rs 结果有一个 while(rs.next()) 循环...我想在 while 之前放置一个 if 语句,以检查 rs 是否为空。我可以用 rs.next 做到这一点吗?它不会在 rs 中向前移动,这样我的循环就不会从第一个结果开始吗? 会的。您将不得不以某种方式处理它 - 例如使用像 @mark-rotteveel 建议的 do-while 循环。根本无法保证在实际获取返回行之前知道返回的行数。【参考方案3】:

实际上,我认为另一种方法可以满足您的需求:

Class.forName("org.exempleDatabase.Driver");
Connection  conn = DriverManager.getConnection("jdbc:exempleDatabase:/../smartytwiti", "username", "password");
ResultSet resset = conn.createStatement().executeQuery("select count(*) from yourTable;");
resset.last();
int resnum = resset.getRow();
if(resnum<1)System.out.println("HEADLINE");

这将获取 ResultSet,移动到集合的最后一行,然后在 resnum 中给出该行的编号。如果您要使用 resset.next() 遍历结果,请记住使用 resset.beforeFirst() 向后移动

希望对您有所帮助。

【讨论】:

【参考方案4】:

在SQL Server上可以放到sql查询中:

COUNT(*) OVER(PARTITION BY 1)

喜欢这里:

select COUNT(*) OVER(PARTITION BY 1) as NUM,ident as ID,employee as EMP from invoice where date between '2017-01-01 00:00:00.000' and '2017-01-31 00:00:00.000'

然后,您会得到如下结果:

NUM, ID,    EMP
4,   28912, JOHN
4,   28913, JOHN
4,   28914, ADAM
4,   28915, PETER

现在,在处理所有数据之前,您可以只读取第一个 col 和第一个单元格来获取记录数。存储结果的对象数组 [invoices] 只声明一次,同时获取 thirst 结果。

Object[][] invoices = null;
Boolean b_inv = false;
[...]
try 
        Statement stmt = db_conn.createStatement();
        boolean results = stmt.execute(sql_query);

        if (results) 
            try (ResultSet rs1 = stmt.getResultSet()) 
                Integer l = 0;

                while (rs1.next()) 
                    if (!b_inv) 
                        invoices = new Object[rs1.getInt(1)][2];
                        b_inv = true;
                    
                    invoices[l][0] = rs1.getInt(1);
                    invoices[l][1] = rs1.getString(2);
                    l++;
                
            
            stmt.close();
        
     catch (SQLException | NumberFormatException dbsi1) 

将记录计数放在 SQL Server 端不是很好吗?

【讨论】:

【参考方案5】:

您可以使用此代码做您想做的事情:

        Class.forName("org.exempleDatabase.Driver");

        Connection  conn = DriverManager.getConnection("jdbc:exempleDatabase:/../smartytwiti", "username", "password");

        ResultSet resset = conn.createStatement().executeQuery("select count(*) from yourTable;");

        resset.next();//set the pointer to the first row(important!)

        if(resset.getInt(1)==0)
            System.out.println("HEADLINE");

【讨论】:

【参考方案6】:

如前所述,getFetchSize 没有得到结果的数量..

你可以做这样的事情。 初始化一个整数并增加它..

 int count = 0
 while(rs.next()) 
    count++;
 

【讨论】:

以上是关于ResultSet getFetchSize() 似乎不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

ResultSet 不为空,但 resultset.next() 返回 false

如果ResultSet取值并存入内存,为啥ResultSet对象关闭后就不能使用了?

查找 ResultSet 列数? [复制]

Mockito - 模拟ResultSet

ResultSet 关闭后不允许出现 ResultSet、空指针异常和 SQLException 操作

Mysql Java Derby Netbeans:不允许“deleteRow”,因为 ResultSet 不是可更新的 ResultSet