Wynik Java Ustaw, jak sprawdzić, czy są jakieś wyniki

311

Zestaw wyników nie ma metody dla hasNext. Chcę sprawdzić, czy zestaw wyników ma jakąkolwiek wartość

czy to właściwy sposób?

if (!resultSet.next() ) {
    System.out.println("no data");
} 
kal
źródło
2
Dla przyszłych czytelników takich jak ja: odpowiedzi, które pomogły mi, to te z Felype i Dermot Doherty
Benj

Odpowiedzi:

237

Zgadza się, początkowo ResultSetkursor wskazuje przed pierwszym wierszem, jeśli pierwsze wywołanie next()return, falseto w danych nie było żadnych danych ResultSet.

Jeśli użyjesz tej metody, być może będziesz musiał zadzwonić beforeFirst()natychmiast po jej zresetowaniu, ponieważ ustawiła się teraz za pierwszym rzędem.

Należy jednak zauważyć, że poniższa odpowiedź Seifera jest bardziej eleganckim rozwiązaniem tego pytania.

dziewięciostronny
źródło
37
Pamiętaj jednak, że jeśli są / są / rzędy, po tym teście będziesz wskazywał na pierwszy rząd. Upewnij się więc, że przypadkowo nie pominiesz rzędu.
Matthew Flaschen
1
Dobrze, że kursor (wskaźnik) wskazuje pierwszy wiersz
JohnMerlino,
@MatthewFlaschen, masz rację, aby rozwiązać problem pominięcia pierwszego wiersza, użyłem do {...} while (rs.next);
Israelm
8
Możesz także zadzwonić, isBeforeFirst()aby sprawdzić, czy są zwracane wiersze bez przesuwania kursora, a następnie postępować normalnie.
SnakeDoc,
528

Zakładając, że pracujesz z nowo zwróconym, ResultSetktórego kursor wskazuje przed pierwszym rzędem, łatwiejszym sposobem sprawdzenia tego jest po prostu wywołanie isBeforeFirst(). Pozwala to uniknąć konieczności śledzenia wstecznego, jeśli dane mają zostać odczytane.

Jak wyjaśniono w dokumentacji , zwraca wartość false, jeśli kursor nie znajduje się przed pierwszym rekordem lub jeśli nie ma wierszy w zestawie wyników .

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

 

Seifer
źródło
15
Dzięki, tak, wiem, ale napotkałem ten sam problem i nie byłem zadowolony z tego, że mogę iść naprzód, aby sprawdzić, a potem przeczytać wstecz. Pomyślałem, że to prostsze rozwiązanie przyniosłoby korzyści również tym, którzy znajdują się w tej samej sytuacji.
Seifer
5
Należy zauważyć, że przynajmniej w przypadku bazy danych DB2 zestaw wyników musi być typu „przewijalnego”. Można to ustawić podczas tworzenia instrukcji do wykonania.
Laurence Dougal Myers,
1
Poniższa odpowiedź Felype jest bardziej kompletna
Tom Howard
Z dokumentacji Oracle: Uwaga: Obsługa metody isBeforeFirst jest opcjonalna dla zestawów wyników z typem zestawu wyników TYPE_FORWARD_ONLY
emi-le
52

zawsze możesz zrobić następny z góry i po prostu sprawdzić pętlę po

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

    do {
     //statement(s)
    } while (resultSet.next());
}
Masłów
źródło
21

Zazwyczaj robiłbyś coś takiego:

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

Jeśli chcesz zgłosić pusty zestaw, dodaj zmienną zliczającą odczytane elementy. Jeśli potrzebujesz przeczytać tylko jeden element, Twój kod jest odpowiedni.

kgiannakakis
źródło
16

Aby być całkowicie pewnym, że zestaw wyników jest pusty lub nie, niezależnie od pozycji kursora, zrobiłbym coś takiego:

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

Ta funkcja zwróci true, jeśli ResultSet jest pusty, false, jeśli nie, lub zgłosi wyjątek SQLException, jeśli ten ResultSet jest zamknięty / niezainicjowany.

Felype
źródło
12

Najlepiej do tego użyć ResultSet.next () wraz ze składnią do {...} while ().

Wywołanie „Check for any results” ResultSet.next () przenosi kursor do pierwszego wiersza, więc użyj składni do {...} while (), aby przetworzyć ten wiersz, jednocześnie kontynuując przetwarzanie pozostałych wierszy zwróconych przez pętlę.

W ten sposób możesz sprawdzić wyniki, a jednocześnie przetwarzać wszystkie zwrócone wyniki.

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());
}
Dermot Doherty
źródło
8

Według najbardziej realnej odpowiedzi sugeruje się użycie „isBeforeFirst ()”. To nie jest najlepsze rozwiązanie, jeśli nie masz typu „tylko do przodu” .

Istnieje metoda o nazwie „ .first () ”. Osiągnięcie dokładnie takiego samego rezultatu jest mniej przesadne. Sprawdzasz, czy coś jest w „zestawie wyników” i nie przesuwasz kursora.

Dokumentacja stwierdza: „(...) fałsz, jeśli w zestawie wyników nie ma wierszy ”.

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

Możesz także wywołać metodę isBeforeFirst (), aby sprawdzić, czy są zwracane wiersze bez przesuwania kursora, a następnie postępować normalnie. - SnakeDoc, 2 września 14 o 19:00

Istnieje jednak różnica między „isBeforeFirst ()” i „first ()”. Najpierw generuje wyjątek, jeśli jest wykonywany na zestawie wyników z typu „tylko do przodu”.

Porównaj dwie sekcje rzutów: 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 ()

Dobra, w zasadzie oznacza to, że powinieneś używać „isBeforeFirst”, o ile masz typ „tylko do przodu”. W przeciwnym razie użycie „first ()” będzie mniej przesadne.

OddDev
źródło
1
W jaki sposób „mniej nadwyżki” daje dokładnie ten sam wynik? Wydaje mi się, że celem first () jest przesunięcie kursora do pierwszego wiersza, jeśli jeszcze go nie ma (i zwrócenie true, jeśli się powiedzie). isBeforeFirst jest jedynie funkcją czysto diagnostyczną i wydaje się bardziej odpowiednia do celów autora. Ponadto sposób, w jaki sformułowanie first () zwraca wartość true, dopóki jest ono „w prawidłowym wierszu” ... co jest dziwne, jak można by pomyśleć, że byłoby sformułowane jako „w pierwszym wierszu”. Dla mnie nie widzę korzyści z używania first () w tym scenariuszu, chyba że kursor jest zaawansowany i nie chcesz przywrócić go do początku.
Jon
5

Działa to, jeśli chcesz sprawdzić, czy w zestawie wyników są wiersze tak.

Pamiętaj, że next()zawsze przenosi się do następnego wiersza, więc jeśli planujesz zrobić odczyt z zestawu wyników, musisz wziąć to pod uwagę.

Zwykłe użycie z ResultSet (podczas zwykłego czytania) to:

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

Co oczywiście nie będzie działać poprawnie, jeśli next()już raz wywołałeś, aby sprawdzić, czy zestaw wyników jest pusty, więc uważaj na to. Chociaż istnieją metody „tworzenia kopii zapasowych”, nie są one obsługiwane dla wszystkich typów zestawów wyników.

Nuoji
źródło
5

Uważam, że jest to praktyczny i łatwy do przeczytania fragment.

        if (res.next()) {
            do {

                // successfully in. do the right things.

            } while (res.next());
        } else {
           // no results back. warn the user.
        }
JSBach
źródło
2
if (!resultSet.isAfterLast() ) {    
System.out.println("No data"); 
} 

isAfterLast() zwraca również false dla pustego zestawu wyników, ale ponieważ kursor i tak jest przed pierwszym wierszem, ta metoda wydaje się bardziej przejrzysta.

Nick Warke
źródło
2
if(resultSet.first) {

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

Ponieważ jeśli ResultSet nie ma raw, to resultSet.firstzwraca false.

użytkownik868927
źródło
Ale przesuwa kursor do pierwszego rzędu niepotrzebny i może mylić dalsze użycie obiektu ob „reset” i może utracić dane
Tigran Babajanyan
Chociaż wygląda to lepiej, nie będzie działać na zestawie wyników kursora tylko do przodu.
eliteproxy
1

Najlepiej jest sprawdzić pierwszy wiersz, aby podczas zbierania danych uniknąć błędu pomijania wiersza. Coś w stylu: if (! ResultSet.first ()) {System.out.println („brak danych”); }

Anthony Oyovwe
źródło
1

Korzystając z resultSet.next (), możesz łatwo uzyskać wynik, niezależnie od tego, czy wynik zawiera dowolną wartość, czy nie

ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next())
 //resultSet contain some values
else
 // empty resultSet
Ram72119
źródło
Nie powtarzaj istniejących odpowiedzi.
james.garriss
1
ResultSet result = stmt.executeQuery(sqlQuery);
if (!result.next())
    status = "ERROR";
else
    status = "SUCCESS";
Deepu Surendran
źródło
1

Próbowałem ustawić bieżący wiersz na pierwszy indeks (zajmujący się kluczami podstawowymi). sugerowałbym

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

Po wypełnieniu ResultSet wskazuje na pierwszy wiersz. Ustawienie go na pierwszy wiersz (wskazany przez rs.absolute(1)) spowoduje zwrócenie wartości true oznaczającej, że został on pomyślnie umieszczony w wierszu 1, lub false, jeśli wiersz nie istnieje. Możemy to ekstrapolować

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

co ustawia bieżący wiersz na pozycję i i zakończy się niepowodzeniem, jeśli wiersz nie istnieje. To tylko alternatywna metoda

while(rs.next()){
    //Code
}
Andrzej
źródło
Jaka jest twoja odpowiedź?
CMedina,
1

Utworzyłem następującą metodę, aby sprawdzić, czy zestaw wyników jest pusty.

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

Bardzo ważne jest, aby wziąć pod uwagę następujące kwestie:

CallableStatementObiekt musi zostać ustawiony, aby pozwolić obiektowi ResultSet przejść na koniec i wrócić na górę.

TYPE_SCROLL_SENSITIVE : Obiekt ResultSet może przesunąć się na końcu i wrócić do góry. Ponadto można złapać ostatnie zmiany.

CONCUR_READ_ONLY : Możemy odczytać dane obiektu ResultSet, ale nie możemy go zaktualizować.

CallableStatement proc = dbconex.prepareCall(select, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
Cristian
źródło
1

Myślę, że najłatwiejszym sposobem sprawdzenia zestawu wyników jest użycie CollectionUtils w pakiecie org.apache.commons.collections.CollectionUtils

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

Spowoduje to sprawdzenie stanu zerowego i pustego zestawu wyników.

Więcej szczegółowych informacji można znaleźć w następującym dokumencie. CollectionUtils

Mitul Maheshwari
źródło
1
ResultSet nie jest kolekcją.
Joachim Lous,
1

Dlaczego nie użyć 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

Dla mnie sprawdź „if (rs.getRow ()! = 0)” wydaje się działać dobrze.

Stiebrs
źródło
0

możesz zrobić coś takiego

boolean found = false;

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

if (!found)
    System.out.println("No Data");
Mohamed EL-Shabrawy
źródło
1
WAAAY zbyt skomplikowane.
jordaniac89
0
ResultSet rs = rs.executeQuery();
if(rs.next())
{
  rs = rs.executeQuery();
  while(rs.next())
  {
    //do code part
  }
}
else
{
  //else if no result set
}

Lepiej jest ponownie wykonać zapytanie, ponieważ kiedy if(rs.next()){....}wywołamy pierwszy wiersz, zostanie wykonany wiersz ResultSet, a po nim while(rs.next()){....}uzyskamy wynik z następnego wiersza. Myślę więc, że ponowne wykonanie zapytania w środku ifjest lepszą opcją.

Arpit Trivedi
źródło
5
-1 To nie jest lepsza opcja. Po co dwukrotnie sprawdzać bazę danych? Co się stanie, jeśli dane drastycznie zmienią się między połączeniami? To marnotrawstwo.
Toby Caulk,
-2

Początkowo obiekt zestawu wyników (rs) wskazuje na BFR (przed pierwszym rekordem). Gdy użyjemy rs.next (), kursor wskazuje na pierwszy rekord, a rs przechowuje „true”. Za pomocą pętli while można wydrukować wszystkie rekordy tabeli. Po pobraniu wszystkich rekordów kursor przesuwa się do ALR (po ostatnim rekordzie) i zostanie ustawiony na zero. Rozważmy, że w tabeli są 2 rekordy.

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

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

Krótko mówiąc, możemy również napisać warunek jako while (rs.next ()).

siedmiodniowa żałoba
źródło
3
Twoja pętla while nie dostanie szansy na operację w pierwszym zwróconym rzędzie, co wydaje się nieco fatalną wadą przy takim podejściu. Istnieje wiele sugestii powyżej, które są lepsze niż ta.
Jules