【问题标题】:how to find number of records in ResultSet如何在结果集中查找记录数
【发布时间】:2012-01-10 09:47:25
【问题描述】:

我在 Oracle 查询后收到 ResultSet。当我遍历ResultSet 时,它会进入无限循环。

ResultSet rs = (ResultSet) // getting from statement
while (rs.next()) {
//
//
}

这个循环没有终止,所以我尝试使用rs.getFetchSize() 查找记录数并返回一个值10。 我想知道这是否是找出 ResultSet 中记录数的正确方法,如果计数为 10,为什么它会进入无限循环。 请发表您的意见。

【问题讨论】:

  • 循环中是否有任何奇怪的代码可能导致挂起?当您使用调试器单步执行时会发生什么?
  • 为什么不尝试将查询更改为计数并计算查询返回的行数...
  • @Cilithium nope.. 有一些 getter 方法调用,仅此而已..
  • @Michael 我正在通过查找方法调用其他服务器中的存储过程,所以我不能这样做。

标签: java jdbc resultset


【解决方案1】:

实际上,ResultSet 并不知道它将返回的实际行数。 事实上,使用分层查询或流水线函数,这个数字也可能是无限的。 10 是结果集应该/将尝试在单个操作中获取的建议行数。 (见下面的评论)。

最好检查您的查询,如果它返回的行数比您预期的多。

【讨论】:

  • getFetchSize() 是结果集应该/将尝试在单个操作中获取的 建议 行数。它没有说明结果集的总大小或到目前为止提取的行数。
【解决方案2】:

要知道存在的记录数,请尝试以下代码

ResultSet rs =  // getting from statement

try {
        boolean b = rs.last();
        int numberOfRecords = 0;
        if(b){
            numberOfRecords = rs.getRow();
        }
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

【讨论】:

  • 你最好从int numberOfRecords = rs.getRow();中删除int
  • 不管怎样,如果循环不成功,这个方法可能也会挂起。
【解决方案3】:

一个简单的 getRowCount 方法如下所示:

private int getRowCount(ResultSet resultSet) {
   if (resultSet == null) {
    return 0;
   }
   try {
       resultSet.last();
       return resultSet.getRow();
   } catch (SQLException exp) {
       exp.printStackTrace();
   } finally {
       try {
          resultSet.beforeFirst();
       } catch (SQLException exp) {
          exp.printStackTrace();
       }
   }
   return 0;
}

您的结果集应该可以滚动以使用此方法。

刚刚看起来这似乎在这个question上的类似行

【讨论】:

    【解决方案4】:

    当你执行一个查询得到一个ResultSet的时候,我会说真的是这个时候你甚至程序本身其实都不知道会返回多少个结果,这种情况很像Oracle CURSOR,就是只需向 Oracle 声明您要执行此类查询,因此我们必须为每个 ResultSet 逐行获取到最后一行。

    正如上面的人已经准备好回答的那样: rs.last 将在这个时候迭代到最后一个程序有能力总共返回多少行。

    【讨论】:

    • 我猜它更糟,它会遍历结果集并将所有行保存在内存中,所以如果出现问题,它可能会因内存不足而导致服务器崩溃。
    【解决方案5】:
    if(res.getRow()>0)
    {
         // Data present in resultset<br>
    }
    else
    {
          //Data not present in resultset<br>
    }
    

    【讨论】:

      【解决方案6】:

      您可以查看下面的 sn-p 代码,您可以在其中找到如何从数据集中计算加载的记录数。此示例使用外部数据集(以 json 格式提供),因此您可以从自己的开始。必要的代码被放置在控制器的脚本中(这个页面是基于 AppPML javascript 并且 cotroller 与加载的 AppPML 对象一起工作)。控制器中的代码返回数据集加载的记录数和数据模型的字段数。

      <!DOCTYPE html>
      <html lang="en-US">
      <title>Customers</title>
      <style>
          body {font: 14px Verdana, sans-serif;}
          h1 { color: #996600; }
          table { width: 100%;border-collapse: collapse; }
          th, td { border: 1px solid grey;padding: 5px;text-align: left; }
          table tr:nth-child(odd) {background-color: #f1f1f1;}
      </style>
      <script src="http://www.w3schools.com/appml/2.0.2/appml.js"></script>
      <body>
          <div appml-data="http://www.w3schools.com/appml/customers.aspx" appml-controller="LukController">
              <h1>Customers</h1>
              <p></p>
              <b>It was loaded {{totalRec}} records in total.</b>
              <p></p>
              <table>
                  <tr>
                      <th>Customer</th>
                      <th>City</th>
                      <th>Country</th>
                  </tr>
                  <tr appml-repeat="records">
                      <td>{{CustomerName}}</td>
                      <td>{{City}}</td>
                      <td>{{Country}}</td>
                  </tr>
              </table>
          </div>
          <script>
              function LukController($appml) {
                  if ($appml.message == "loaded") {
                      $appml.totalRec = Object.keys($appml.data.records).length;
                  }
              }
              // *****************************************************************
              // Message	Description
              //
              // ready	Sent after AppML is initiated, and ready to load data.
              // loaded	Sent after AppML is fully loaded, ready to display data.
              // display	Sent before AppML displays a data item.
              // done	    Sent after AppML is done (finished displaying).
              // submit	Sent before AppML submits data.
              // error	Sent after AppML has encountered an error.
              // *****************************************************************
          </script>
      </body>
      
      </html>

      【讨论】:

        【解决方案7】:

        我得到了答案:- 以下是您需要遵循的步骤:

        1. 确保您使用的是选择查询(例如 select * from employee)。
        2. 不要使用计数查询(例如 select count(*) from employee)。

        然后使用以下步骤:

        Statement stmt=conn.createStatement();
        ResultSet rs=stmt.executeQuery("select * from employee");
            while(rs.next()){
                rowCount++;
            }
            return rowCount;
        }
        

        其中rsResultSet 的对象。

        然后您将获得确切的行数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-10
          • 2013-05-01
          • 2013-11-08
          • 2018-07-09
          • 2011-01-31
          • 1970-01-01
          • 2015-03-02
          • 2013-09-12
          相关资源
          最近更新 更多