Kết quả Java Đặt cách kiểm tra nếu có bất kỳ kết quả nào


311

Resultset không có phương thức cho hasNext. Tôi muốn kiểm tra xem kết quả có giá trị nào không

đây có phải là cách chính xác

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

2
Đối với độc giả trong tương lai như tôi: câu trả lời giúp tôi là những từ Felype và Dermot Doherty
Benj

Câu trả lời:


238

Điều đó đúng, ban đầu ResultSetcon trỏ sẽ trỏ đến trước hàng đầu tiên, nếu cuộc gọi đầu tiên next()trả về falsethì không có dữ liệu trong ResultSet.

Nếu bạn sử dụng phương pháp này, bạn có thể phải gọi beforeFirst()ngay sau đó để đặt lại, vì nó đã tự định vị qua hàng đầu tiên ngay bây giờ.

Tuy nhiên, cần lưu ý rằng câu trả lời của Seifer dưới đây là một giải pháp thanh lịch hơn cho câu hỏi này.


37
Nhưng hãy nhớ, nếu có / are / rows, sau bài kiểm tra đó, bạn sẽ chỉ vào hàng đầu tiên. Vì vậy, hãy chắc chắn rằng bạn không vô tình bỏ qua một hàng.
Matthew Flaschen

1
Điểm hay là con trỏ (con trỏ) đang chỉ vào hàng đầu tiên
JohnMerlino

@MatthewFlaschen, bạn đã đúng, để giải quyết vấn đề bỏ qua hàng đầu tiên, tôi đã sử dụng một {...} while (rs.next);
Israel

8
Bạn cũng có thể chỉ cần gọi isBeforeFirst()để kiểm tra nếu có bất kỳ hàng nào được trả về mà không tiến con trỏ, sau đó tiến hành bình thường.
SnakeDoc

528

Giả sử bạn đang làm việc với một người mới được trả về ResultSetcó con trỏ đang trỏ trước hàng đầu tiên, một cách dễ dàng hơn để kiểm tra điều này là chỉ gọiisBeforeFirst() . Điều này tránh phải theo dõi ngược lại nếu dữ liệu được đọc.

Như đã giải thích trong tài liệu , điều này trả về false nếu con trỏ không ở trước bản ghi đầu tiên hoặc nếu không có hàng nào trong Kết quả .

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

 


15
Cảm ơn, vâng tôi biết nhưng tôi đã gặp phải vấn đề tương tự và không hài lòng với cái nhìn tiến về phía trước để kiểm tra rồi lùi lại để đọc. Tôi nghĩ giải pháp đơn giản hơn này cũng sẽ có lợi cho những người khác có cùng hoàn cảnh.
Seifer

5
Lưu ý rằng, ít nhất là đối với DB2, tập kết quả phải là loại "có thể cuộn". Điều này có thể được đặt khi bạn tạo câu lệnh sẽ được thực thi.
Laurence Dougal Myers


Từ Tài liệu Oracle: Lưu ý: Hỗ trợ cho phương thức isB BeforeFirst là tùy chọn cho Kết quả với loại tập kết quả TYPE_FORWARD_ONLY
emi-le

52

bạn luôn có thể thực hiện tiếp theo và chỉ cần kiểm tra vòng lặp bài

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

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

21

Bạn thường sẽ làm một cái gì đó như thế này:

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

Nếu bạn muốn báo cáo một tập hợp trống, hãy thêm một biến đếm các mục đã đọc. Nếu bạn chỉ cần đọc một mục duy nhất, thì mã của bạn là đủ.


16

Để hoàn toàn chắc chắn thay vì tập kết quả trống hay không bất kể vị trí con trỏ, tôi sẽ làm một cái gì đó như thế này:

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

Hàm này sẽ trả về true nếu Kết quả trống, sai nếu không hoặc ném ra một biểu thức SQLEx nếu Kết quả đó bị đóng / chưa được khởi tạo.


12

Tốt nhất để sử dụng resultIn.next () cùng với cú pháp do {...} while () cho việc này.

Gọi "kiểm tra bất kỳ kết quả nào" gọi result Set.next () di chuyển con trỏ đến hàng đầu tiên, vì vậy hãy sử dụng cú pháp do {...} while () để xử lý hàng đó trong khi tiếp tục xử lý các hàng còn lại được trả về bởi vòng lặp.

Bằng cách này, bạn có thể kiểm tra bất kỳ kết quả nào, đồng thời xử lý bất kỳ kết quả nào được trả về.

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());
}

8

Theo câu trả lời khả thi nhất, gợi ý là sử dụng "isB BeforeFirst ()". Đó không phải là giải pháp tốt nhất nếu bạn không có "loại chỉ chuyển tiếp" .

Có một phương thức gọi là " .first () ". Sẽ ít quá mức để có được kết quả chính xác như vậy. Bạn kiểm tra xem có cái gì trong "tập kết quả" của bạn không và không tiến con trỏ của bạn.

Tài liệu nêu rõ: "(...) sai nếu không có hàng trong tập kết quả ".

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

Bạn cũng có thể chỉ cần gọi isB BeforeFirst () để kiểm tra xem có hàng nào được trả về mà không tiến con trỏ hay không, sau đó tiến hành bình thường. - SnakeDoc ngày 2 tháng 9 năm 14 lúc 19:00

Tuy nhiên, có một sự khác biệt giữa "isB BeforeFirst ()" và "first ()". Đầu tiên tạo ra một ngoại lệ nếu được thực hiện trên tập kết quả từ loại "chỉ chuyển tiếp".

So sánh hai phần ném: http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#isB BeforeFirst () http://docs.oracle.com/javase/7/docs /api/java/sql/ResultSet.html#first ()

Được rồi, về cơ bản, điều này có nghĩa là bạn nên sử dụng "isB BeforeFirst" miễn là bạn có loại "chỉ chuyển tiếp". Nếu không, sẽ ít quá mức để sử dụng "first ()".


1
Làm thế nào là "ít quá mức" để có được kết quả chính xác như vậy? Dường như với tôi, mục đích đầu tiên () là di chuyển con trỏ đến hàng đầu tiên nếu nó chưa ở đó (và trả về true nếu thành công). isB BeforeFirst chỉ là một chức năng chẩn đoán đơn thuần và có vẻ phù hợp hơn với mục đích của tác giả. Thêm vào đó, cách đầu tiên () được diễn đạt, nó trả về đúng miễn là "trên một hàng hợp lệ" ... thật kỳ lạ khi người ta nghĩ nó sẽ được gọi là "trên hàng đầu tiên". Đối với tôi, tôi không thấy lợi thế của việc sử dụng First () trong kịch bản này trừ khi con trỏ của bạn đã nâng cao và bạn muốn đưa nó trở lại từ đầu.
Jon

5

Điều đó sẽ hoạt động nếu bạn muốn xem nếu có bất kỳ hàng nào trong tập kết quả có.

Lưu ý rằng next()luôn luôn chuyển sang hàng tiếp theo, vì vậy nếu bạn dự định thực hiện bất kỳ việc đọc nào từ tập kết quả, bạn cần phải tính đến điều đó.

Cách sử dụng thông thường với result Set (khi chỉ cần đọc) là:

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

Điều này rõ ràng sẽ không hoạt động chính xác nếu bạn đã gọi next()một lần để kiểm tra xem tập kết quả có trống không, vì vậy hãy coi chừng điều đó. Mặc dù có các phương pháp để "sao lưu", nhưng chúng không được hỗ trợ cho tất cả các loại tập kết quả.


5

Đây là một phần thực tế và dễ đọc tôi tin.

        if (res.next()) {
            do {

                // successfully in. do the right things.

            } while (res.next());
        } else {
           // no results back. warn the user.
        }

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

isAfterLast() cũng trả về false cho tập kết quả trống nhưng vì con trỏ nằm trước hàng đầu tiên, nên phương thức này có vẻ rõ ràng hơn.


2
if(resultSet.first) {

} else { 
    system.out.println("No raw or resultSet is empty");
}

Bởi vì nếu result Set không có raw thì resultSet.firsttrả về false.


Nhưng nó di chuyển con trỏ đến hàng đầu tiên không cần thiết và nó có thể gây nhầm lẫn khi sử dụng thêm đối tượng ob "reset" và có thể bị mất dữ liệu
Tigran Babajanyan

Mặc dù điều này có vẻ tốt hơn, nhưng nó sẽ không hoạt động trên một kết quả con trỏ chỉ chuyển tiếp.
eliteproxy

1

Điều tốt nhất để làm là kiểm tra hàng đầu tiên để khi bạn có ý định lấy dữ liệu, bạn có thể tránh được lỗi bỏ qua một hàng. Một cái gì đó như: if (! Resultset.first ()) {System.out.println ("không có dữ liệu"); }


1

Bằng cách sử dụng resultset.next (), bạn có thể dễ dàng nhận được kết quả, cho dù resultset có chứa bất kỳ giá trị nào hay không

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

Đừng lặp lại câu trả lời hiện có.
james.garriss 13/03/2015

1
ResultSet result = stmt.executeQuery(sqlQuery);
if (!result.next())
    status = "ERROR";
else
    status = "SUCCESS";

1

Tôi đã cố gắng đặt hàng hiện tại thành chỉ mục đầu tiên (xử lý các khóa chính). Tôi sẽ đề nghị

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

Khi Kết quả được điền, nó sẽ trỏ đến trước hàng đầu tiên. Khi đặt nó thành hàng đầu tiên (được chỉ định bởi rs.absolute(1)), nó sẽ trả về biểu thị đúng, nó được đặt thành công ở hàng 1 hoặc sai nếu hàng không tồn tại. Chúng ta có thể ngoại suy điều này để

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

sẽ đặt hàng hiện tại thành vị trí i và sẽ thất bại nếu hàng không tồn tại. Đây chỉ là một phương pháp thay thế cho

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

Câu trả lời của bạn là gì?
CMedina

1

Tôi đã tạo phương thức sau để kiểm tra xem Kết quả có trống không.

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

Điều rất quan trọng là phải có những cân nhắc sau:

Đối tượng CallableStatement phải được xử lý để cho phép đối tượng result Set đi đến cuối và quay lại đầu trang.

TYPE_SCROLL_SENSITIVE : Đối tượng result Set có thể dịch chuyển ở cuối và quay lại đầu trang. Hơn nữa có thể nắm bắt những thay đổi cuối cùng.

CONCUR_READ_ONLY : Chúng tôi có thể đọc dữ liệu đối tượng Kết quả, nhưng không thể cập nhật.

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

1

Tôi nghĩ rằng cách dễ nhất để kiểm tra tập kết quả là thông qua CollectionUtils trong gói org.apache.commons.collections.CollectionUtils

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

Điều này sẽ kiểm tra null cũng như điều kiện thiết lập kết quả trống.

Để biết thêm thông tin chi tiết, bạn có thể tham khảo tài liệu sau đây. Bộ sưu tập


1
Kết quả không phải là một Bộ sưu tập.
Joachim Lous

1

Tại sao không sử dụng 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

Đối với tôi, hãy kiểm tra "if (rs.getRow ()! = 0)" có vẻ hoạt động tốt.


0

bạn có thể làm một cái gì đó như thế này

boolean found = false;

while ( resultSet.next() )
{
    found = true;
    resultSet.getString("column_name");
}

if (!found)
    System.out.println("No Data");

1
WAAAY quá phức tạp.
jordaniac89

0
ResultSet rs = rs.executeQuery();
if(rs.next())
{
  rs = rs.executeQuery();
  while(rs.next())
  {
    //do code part
  }
}
else
{
  //else if no result set
}

Tốt hơn là thực hiện lại truy vấn bởi vì khi chúng tôi gọi if(rs.next()){....}hàng đầu tiên của Bộ while(rs.next()){....}kết quả sẽ được thực thi và sau đó bên trong chúng tôi sẽ nhận được kết quả từ dòng tiếp theo. Vì vậy, tôi nghĩ rằng thực hiện lại truy vấn bên trong iflà lựa chọn tốt hơn.


5
-1 Đây không phải là một lựa chọn tốt hơn. Tại sao truy vấn cơ sở dữ liệu hai lần? Điều gì xảy ra nếu dữ liệu thay đổi mạnh mẽ giữa các cuộc gọi? Điều này là lãng phí.
Toby Caulk

-2

Ban đầu, đối tượng tập kết quả (rs) trỏ đến BFR (trước bản ghi đầu tiên). Khi chúng tôi sử dụng rs.next (), con trỏ trỏ đến bản ghi đầu tiên và rs giữ "true". Sử dụng vòng lặp while bạn có thể in tất cả các bản ghi của bảng. Sau khi tất cả các bản ghi được truy xuất, con trỏ di chuyển đến ALR (Sau bản ghi cuối cùng) và nó sẽ được đặt thành null. Hãy để chúng tôi xem xét rằng có 2 hồ sơ trong bảng.

if(rs.next()==false){
    // there are no records found
    }    

while (rs.next()==true){
    // print all the records of the table
    }

Tóm lại, chúng ta cũng có thể viết điều kiện là while (rs.next ()).


3
Vòng lặp while của bạn sẽ không có cơ hội hoạt động ở hàng đầu tiên được trả về, có vẻ như là một lỗ hổng nghiêm trọng với cách tiếp cận này. Có rất nhiều gợi ý ở trên tốt hơn cái này.
Jules
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.