【问题标题】:Java ResultSet how to check if there are any resultsJava ResultSet如何检查是否有任何结果
【发布时间】:2010-10-26 09:58:17
【问题描述】:

Resultset 没有 hasNext 的方法。我想检查结果集是否有任何值

这是正确的方法吗

if (!resultSet.next() ) {
    System.out.println("no data");
} 

【问题讨论】:

  • 对于像我这样的未来读者:对我有帮助的答案来自 Felype 和 Dermot Doherty

标签: java jdbc


【解决方案1】:

假设您正在使用新返回的ResultSet,其光标指向第一行之前,更简单的检查方法是调用isBeforeFirst()。这样可以避免在读取数据时必须回溯。

As explained in the documentation,如果光标不在第一条记录之前或ResultSet 中没有行,则返回false。

if (!resultSet.isBeforeFirst() ) {    
    System.out.println("No data"); 
} 

 

【讨论】:

  • 谢谢,是的,我知道,但是我遇到了同样的问题,并且对向前检查然后向后阅读的样子不满意。我认为这种更简单的解决方案也会使处于相同情况的其他人受益。
  • 请注意,至少对于 DB2,结果集必须是“可滚动”类型。这可以在创建要执行的语句时设置。
  • 来自 Oracle 文档:注意:对于结果集类型为 TYPE_FORWARD_ONLY 的 ResultSet,isBeforeFirst 方法的支持是可选的
【解决方案2】:

没错,最初ResultSet的光标指向第一行之前,如果第一次调用next()返回false,那么ResultSet中没有数据。

如果您使用此方法,您可能必须立即调用beforeFirst() 来重置它,因为它现在已经将自己定位到第一行之外。

但是应该注意,下面的Seifer's answer 是这个问题的更优雅的解决方案。

【讨论】:

  • 但请记住,如果有 /are/ 行,那么在测试之后您将指向第一行。因此,请确保您不会意外跳过一行。
  • 光标(指针)指向第一行的好点
  • @MatthewFlaschen,你说得对,为了解决跳过第一行的问题,我使用了 do { ... } while (rs.next);
  • 你也可以直接调用isBeforeFirst()测试是否有行不前进光标返回,然后正常进行。
【解决方案3】:

你总是可以先做下一个,然后做一个循环后检查

if (!resultSet.next() ) {
    System.out.println("no data");
} else {

    do {
     //statement(s)
    } while (resultSet.next());
}

【讨论】:

    【解决方案4】:

    为了完全确定结果集是否为空,无论光标位置如何,我都会这样做:

    public static boolean isMyResultSetEmpty(ResultSet rs) throws SQLException {
        return (!rs.isBeforeFirst() && rs.getRow() == 0);
    }
    

    如果 ResultSet 为空,此函数将返回 true,否则返回 false;如果 ResultSet 关闭/未初始化,则抛出 SQLException。

    【讨论】:

      【解决方案5】:

      你通常会这样做:

      while ( resultSet.next() ) { 
         // Read the next item
         resultSet.getString("columnName");
      }
      

      如果要报告空集,请添加一个变量来计算读取的项目。如果您只需要阅读单个项目,那么您的代码就足够了。

      【讨论】:

        【解决方案6】:

        最好使用 ResultSet.next() 和 do {...} while() 语法。

        “检查任何结果”调用 ResultSet.next() 将光标移动到第一行,因此使用 do {...} while() 语法处理该行,同时继续处理由循环。

        这样您可以检查任何结果,同时还可以处理返回的任何结果。

        if(resultSet.next()) { // Checks for any results and moves cursor to first row,
            do { // Use 'do...while' to process the first row, while continuing to process remaining rows
        
            } while (resultSet.next());
        }
        

        【讨论】:

          【解决方案7】:

          根据最可行的答案,建议是使用“isBeforeFirst()”。 如果您没有“仅转发类型”,这不是最佳解决方案

          有一个方法叫做“.first()”。获得完全相同的结果并不那么矫枉过正。您检查“结果集中”中是否有某些内容,并且不要前进光标。

          文档指出:“(...) false if there are no rows in the result set”。

          if(rs.first()){
              //do stuff      
          }
          

          你也可以直接调用 isBeforeFirst() 来测试是否有任何行返回而不推进游标,然后正常进行。 – SnakeDoc 2014 年 9 月 2 日 19:00

          但是,“isBeforeFirst()”和“first()”是有区别的。如果在“仅向前”类型的结果集上完成,首先会生成一个异常。

          比较两个投掷部分: http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#isBeforeFirst() http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#first()

          好的,基本上这意味着您应该使用“isBeforeFirst”,只要您有“仅转发”类型。否则使用“first()”就不会那么矫枉过正了。

          【讨论】:

          • 获得完全相同的结果如何“不那么矫枉过正”?在我看来, first() 的目的是如果光标不存在则将光标移动到第一行(如果成功则返回 true)。 isBeforeFirst 只是一个纯粹的诊断功能,似乎更适合作者的目的。另外,first() 的措辞方式,只要它是“在有效行上”,它就会返回真......这很奇怪,因为人们会认为它会被措辞为“在第一行”。对我来说,我看不到在这种情况下使用 first() 的优势,除非你的光标已经前进并且你想把它带回到开头。
          【解决方案8】:

          如果您想查看结果集中是否有任何行,那将是可行的。

          请注意,next() 总是移动到下一行,因此如果您打算从结果集中读取任何内容,则需要考虑到这一点。

          ResultSet 的通常用法(简单阅读时)是:

          while (resultSet.next())
          {
             ... read from the row here ...
          }
          

          如果您已经调用了一次next() 来检查结果集是否为空,这显然将无法正常工作,因此请注意这一点。虽然有“备份”的方法,但并非所有类型的结果集都支持它们。

          【讨论】:

            【解决方案9】:

            我相信这是一篇实用且易于阅读的文章。

                    if (res.next()) {
                        do {
            
                            // successfully in. do the right things.
            
                        } while (res.next());
                    } else {
                       // no results back. warn the user.
                    }
            

            【讨论】:

              【解决方案10】:

              为什么不使用 rs.getRow()?

              int getRow()
                         throws SQLException
              Retrieves the current row number. The first row is number 1, the second number 2, and so on.
              Note:Support for the getRow method is optional for ResultSets with a result set type of TYPE_FORWARD_ONLY
              
              Returns:
              the current row number; 0 if there is no current row
              Throws:
              SQLException - if a database access error occurs or this method is called on a closed result set
              SQLFeatureNotSupportedException - if the JDBC driver does not support this method
              Since:
              1.2
              

              对我来说,检查“if (rs.getRow() != 0)” 似乎工作得很好。

              【讨论】:

                【解决方案11】:
                if (!resultSet.isAfterLast() ) {    
                System.out.println("No data"); 
                } 
                

                isAfterLast() 也为空结果集返回 false,但由于游标无论如何都在第一行之前,因此这种方法似乎更清晰。

                【讨论】:

                  【解决方案12】:
                  if(resultSet.first) {
                  
                  } else { 
                      system.out.println("No raw or resultSet is empty");
                  }
                  

                  因为如果 ResultSet 没有 raw 则 resultSet.first 返回 false。

                  【讨论】:

                  • 但它会不必要地将光标移动到第一行,并且会混淆进一步使用 ob "reset" 对象并可能丢失数据
                  • 虽然这看起来更好,但它不适用于仅向前游标结果集。
                  【解决方案13】:

                  最好的办法是检查第一行,这样当你打算获取数据时,就可以避免跳过一行的错误。类似于: if (!resultSet.first() ) { System.out.println("no data"); }

                  【讨论】:

                    【解决方案14】:

                    通过使用 resultSet.next() 可以很容易地得到结果,无论 resultSet 是否包含任何值

                    ResultSet resultSet = preparedStatement.executeQuery();
                    if(resultSet.next())
                     //resultSet contain some values
                    else
                     // empty resultSet
                    

                    【讨论】:

                    • 不要重复已有的答案。
                    【解决方案15】:
                    ResultSet result = stmt.executeQuery(sqlQuery);
                    if (!result.next())
                        status = "ERROR";
                    else
                        status = "SUCCESS";
                    

                    【讨论】:

                      【解决方案16】:

                      我一直在尝试将当前行设置为第一个索引(处理主键)。我会建议

                      if(rs.absolute(1)){
                          System.out.println("We have data");
                      } else {
                          System.out.println("No data");
                      }
                      

                      填充 ResultSet 时,它指向第一行之前。将其设置为第一行(由rs.absolute(1) 表示)时,它将返回 true 表示它已成功放置在第 1 行,如果该行不存在,则返回 false。我们可以将其推断为

                      for(int i=1; rs.absolute(i); i++){
                          //Code
                      }
                      

                      将当前行设置为位置 i 并且如果该行不存在将失败。这只是一种替代方法

                      while(rs.next()){
                          //Code
                      }
                      

                      【讨论】:

                      • 你的答案是什么?
                      【解决方案17】:

                      我创建了以下方法来检查 ResultSet 是否为空。

                      public static boolean resultSetIsEmpty(ResultSet rs){        
                          try {
                              // We point the last row
                              rs.last();
                              int rsRows=rs.getRow(); // get last row number
                      
                              if (rsRows == 0) {
                                  return true;
                              }
                      
                              // It is necessary to back to top the pointer, so we can see all rows in our ResultSet object.
                              rs.beforeFirst();
                              return false;
                          }catch(SQLException ex){            
                              return true;
                          }
                      }
                      

                      注意以下几点非常重要:

                      CallableStatement 对象必须设置为让 ResultSet 对象走到最后并返回顶部。

                      TYPE_SCROLL_SENSITIVE:ResultSet 对象可以在末尾移动并返回顶部。进一步可以捕捉最后的变化。

                      CONCUR_READ_ONLY:我们可以读取ResultSet对象数据,但是不能更新。

                      CallableStatement proc = dbconex.prepareCall(select, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
                      

                      【讨论】:

                        【解决方案18】:

                        我认为检查结果集最简单的方法是通过 org.apache.commons.collections.CollectionUtils 包下的 CollectionUtils

                        if(CollectionUtils.isNotEmpty(resultList)){
                          /**
                          * do some stuff
                          */
                        }
                        

                        这将检查 null 以及空结果集条件。

                        有关更多详细信息,您可以参考以下文档。 CollectionUtils

                        【讨论】:

                        • ResultSet 不是一个集合。
                        【解决方案19】:

                        你可以这样做

                        boolean found = false;
                        
                        while ( resultSet.next() )
                        {
                            found = true;
                            resultSet.getString("column_name");
                        }
                        
                        if (!found)
                            System.out.println("No Data");
                        

                        【讨论】:

                        • 太复杂了。
                        【解决方案20】:
                        ResultSet rs = rs.executeQuery();
                        if(rs.next())
                        {
                          rs = rs.executeQuery();
                          while(rs.next())
                          {
                            //do code part
                          }
                        }
                        else
                        {
                          //else if no result set
                        }
                        

                        最好重新执行查询,因为当我们调用if(rs.next()){....} 时,ResultSet 的第一行将被执行,然后在while(rs.next()){....} 中,我们将从下一行得到结果。所以我认为在if 内重新执行查询是更好的选择。

                        【讨论】:

                        • -1 这不是一个更好的选择。为什么要查询数据库两次?如果数据在调用之间发生剧烈变化怎么办?这是浪费。
                        【解决方案21】:
                        if (resultSet==null ) {
                            System.out.println("no data");
                        }
                        

                        【讨论】:

                          【解决方案22】:

                          请注意,

                          如果您使用的是org.springframework.jdbc.core.RowMapper 要非常小心如何检查 ResultSet 是否为空,因为 以下适用于 mapRow 方法:

                          此方法不应在 ResultSet 上调用 next();它只应该映射当前行的值。

                          在这种情况下,您的支票可能会变成类似

                          resultSet.beforeFirst();
                          if (!resultSet.next() ) {
                              System.out.println("no data");
                          } 
                          

                          【讨论】:

                            【解决方案23】:

                            最初,结果集对象 (rs) 指向 BFR(在第一条记录之前)。一旦我们使用 rs.next(),光标指向第一条记录并且 rs 保持“真”。使用 while 循环,您可以打印表的所有记录。检索到所有记录后,光标移动到 ALR(最后一条记录之后),并将其设置为空。假设表中有 2 条记录。

                            if(rs.next()==false){
                                // there are no records found
                                }    
                            
                            while (rs.next()==true){
                                // print all the records of the table
                                }
                            

                            简而言之,我们也可以将条件写成 while (rs.next())。

                            【讨论】:

                            • 您的 while 循环将没有机会对返回的第一行进行操作,这似乎是这种方法的致命缺陷。上面有很多比这个更好的建议。
                            猜你喜欢
                            • 2014-03-01
                            • 1970-01-01
                            • 2012-05-15
                            • 2014-12-20
                            • 2017-08-18
                            • 2018-06-18
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多