25

如何使用 JDBC 检查结果集是否有一行或多行?

4

7 回答 7

32
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
boolean isMoreThanOneRow = rs.first() && rs.next();

你没有问这个,但你可能需要它:

boolean isEmpty = ! rs.first();

通常,我们不需要行数,因为我们使用 WHILE 循环而不是 FOR 循环来迭代结果集:

ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
while (rs.next()) {
    // retrieve and print the values for the current row
    int i = rs.getInt("a");
    String s = rs.getString("b");
    float f = rs.getFloat("c");
    System.out.println("ROW = " + i + " " + s + " " + f);
}

但是,在某些情况下,您可能希望对结果进行窗口化,并且您需要提前将记录计数显示给用户,例如Row 1 to 10 of 100. 您可以使用 first 进行单独的查询SELECT COUNT(*),以获取记录计数,但请注意,该计数只是近似值,因为可以在执行两个查询所需的时间之间添加或删除行。

ResultSet 概览中的示例

于 2010-04-07T10:57:31.287 回答
1

有很多选择,由于你没有提供更多的上下文,剩下的就是猜测。我的答案按复杂性和性能升序排序。

  1. 只需运行select count(1) FROM ...并获得答案。您必须运行另一个实际选择并返回数据的查询。
  2. 迭代rs.next()并计数,直到您满意为止。然后,如果您仍然需要实际数据重新运行相同的查询。
  3. 如果您的驱动程序支持向后迭代,请执行rs.next()几次,然后使用rs.previous().
于 2010-04-07T10:59:17.113 回答
1

为此,您不需要 JDBC。通常的习惯用法是将所有结果收集到一个集合中,并利用集合方法,例如List#size().

List<Item> items = itemDAO.list();

if (items.isEmpty()) {
    // It is empty!
if (items.size() == 1) {
    // It has only one row!
} else {
    // It has more than one row!
}

list()方法看起来像这样的地方:

public List<Item> list() throws SQLException {
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    List<Item> items = new ArrayList<Item>();

    try {
        connection = database.getConnection();
        statement = connection.createStatement();
        resultSet = statement.executeQuery(SQL_LIST);
        while (resultSet.next()) {
            Item item = new Item();
            item.setId(resultSet.getLong("id"));
            item.setName(resultSet.getString("name"));
            // ...
            items.add(item);
        }
    } finally {
        if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
        if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
        if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
    }

    return items;
}
于 2010-04-07T11:55:54.903 回答
0

我的简单建议:获取第一个结果行,然后尝试获取下一个结果行。如果尝试成功,则您有不止一排。

如果有不止一行并且您想要处理该数据,则需要缓存第一行中的内容,或者使用可滚动的结果集,以便您可以在查看结果之前返回顶部。

您还可以通过SELECT COUNT(*)对查询的其余部分执行 a 来直接向 SQL 询问此信息;结果将是 0、1 或更多,具体取决于查询的其余部分将返回多少行。这很容易实现,但涉及对数据库的两个查询,假设您接下来要读取和处理实际查询。

于 2010-04-07T10:55:27.367 回答
0

如果要确保恰好有一行,可以确保第一行是最后一行:

ResultSet rs = stmt.executeQuery("SELECT a FROM Table1 WHERE b=10");
if (rs.isBeforeFirst() && rs.next() && rs.isFirst() && rs.isLast()) {
    // Logic for where there's exactly 1 row
    Long valA = rs.getLong("a");    
    // ... 
} 
else {  
    // More that one row or 0 rows returned.    
    // .. 
}
于 2017-08-22T16:00:54.030 回答
0

此实现允许您检查查询结果是否为空,代价是复制一些行。

ResultSet result = stmt.executeQuery("SELECT * FROM Table");

if(result.next()) {
   // Duplicate the code which should be pasted inside while
   System.out.println(result.getInt(1));
   System.out.println(result.getString(2));

   while(result.next()){
   System.out.println(result.getInt(1));
   System.out.println(result.getString(2));
   }
}else{
System.out.println("Query result is empty");
}

缺点:

  1. 在这个实现中,部分代码将被复制。
  2. 您无法知道结果中有多少行。
于 2019-06-14T20:26:03.847 回答
-6

ResultSetMetaData使用类获取行数。

从您的代码中,您可以创建ResultSetMetaData如下:

ResultSetMetaData rsmd = resultSet.getMetaData();   //get ResultSetMetaData
rsmd.getColumnCount();       // get row count from resultsetmetadata
于 2011-07-29T10:34:44.973 回答