2010-04-07 61 views
21

如何檢查結果集是否有一行或多行使用JDBC?如何檢查結果集是否有一行或更多?

+0

這確實是JDBC中缺少的東西,原因是並非所有的數據庫系統都支持rt事先獲取結果集的大小(因爲結果不被預取)。不幸的是,這意味着你不能在支持MySQL的數據庫中輕鬆使用這些功能。 – Thirler 2010-04-07 11:25:18

+0

[Java ResultSet如何檢查是否有任何結果]的可能重複(http://stackoverflow.com/questions/867194/java-resultset-how-to-check-if-there-are-any-results) – rogerdpack 2014-10-06 12:17:45

回答

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

你沒有問這一個,但你可能會需要它:

boolean isEmpty = ! rs.first(); 

通常情況下,因爲我們使用循環遍歷結果集進行迭代,我們不需要行數而不是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。您可以首先使用SELECT COUNT(*)進行單獨查詢,以獲取記錄計數,但請注意計數僅爲近似值,因爲可以在執行兩個查詢所需的時間之間添加或刪除行。

樣品從ResultSet Overview

+0

isMoreThanOneRow會給我錯誤,請求的操作在僅向前結果集上不受支持。 – 2016-02-18 21:49:37

+0

@ Vodo-SioskBaas,您需要在執行'executeQuery'語句之後執行該操作,以便'first()'不需要倒回或更改光標,以便它可以倒回。 – 2016-02-21 17:36:19

0

我毫無頭緒的建議:取第一個結果行,然後嘗試取下一行。如果嘗試成功,您有多行。

如果有多行並且想要處理該數據,則需要緩存第一行的內容,或者使用可滾動的結果集,以便在返回之前可以回到頂部結果。

您還可以通過對查詢的其餘部分執行SELECT COUNT(*)來直接詢問SQL的這些信息;結果將爲0,1或更多,具體取決於查詢的其餘部分將返回多少行。這很容易實現,但涉及對數據庫的兩個查詢,假設您將要讀取並處理下一個實際查詢。

1

有很多選擇,因爲你沒有提供更多的上下文留下的唯一的事情就是猜測。我的答案按照複雜性和性能升序排序。

  1. 只需運行select count(1) FROM ...並獲得答案。您必須運行另一個實際選擇並返回數據的查詢。
  2. rs.next()迭代,直到你快樂。那麼如果你仍然需要實際的數據重新運行相同的查詢。
  3. 如果您的驅動程序支持向後迭代,請執行rs.next()幾次,然後再回到rs.previous()
+2

如果你的驅動不支持向後迭代,'first()'通常重新開始。 – 2010-04-07 11:18:30

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

這並不很好。如果結果集有數百萬行呢? – mindas 2010-04-07 12:05:50

+0

@mindas:那麼'SELECT * FROM table'就沒有意義了。那麼你需要'SELECT COUNT(*)FROM table'。 JDBC並不是這個特定用途的正確工具,這正是在JDBC中不存在虛擬的ResultSet#size()方法的原因。 – BalusC 2010-04-07 12:16:26

+0

原來的問題從來沒有說過它正在做'SELECT * FROM table',我也沒有提出這個問題。原始問題還沒有得到所有數據實際上都是必需的假設。 – mindas 2010-04-07 12:41:25

-4

獲取使用ResultSetMetaData類的行數。

從你的代碼ü可以創建ResultSetMetaData像:

ResultSetMetaData rsmd = resultSet.getMetaData(); //get ResultSetMetaData 
rsmd.getColumnCount();  // get row count from resultsetmetadata 
+0

-1 ResultSetMetaData與行計數無關.. rsmd.getColumnCount()爲您提供結果集的列數 – bluish 2011-11-18 09:07:07

-1
public int rowCountValue(ResultSet rsValue) throws SQLException { 
    ResultSet rowCountValue = rsValue; 
    int countRow = 0; 
    while (rowCountValue.next()) { 
     countRow++; 
    } 
    return countRow; 
} 
+0

爲什麼投票結果不準確,請讓我們知道問題,因爲代碼有效 – 2016-08-27 12:46:16

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.  
    // .. 
} 
相關問題