Java ResultSet como verificar se existem resultados

311

O conjunto de resultados não possui método para o hasNext. Quero verificar se o resultadoSet tem algum valor

Esta é a maneira correta

if (!resultSet.next() ) {
    System.out.println("no data");
} 
kal
fonte
2
Para futuros leitores como eu: respostas que me ajudaram são os da Felype e Dermot Doherty
Benj

Respostas:

238

Isso está correto, inicialmente o ResultSetcursor do apontador está apontando antes da primeira linha, se a primeira chamada para next()retornar false, não havia dados no ResultSet.

Se você usar esse método, poderá ser necessário chamar beforeFirst()imediatamente depois para redefini-lo, pois ele se posicionou após a primeira linha agora.

Deve-se notar, no entanto, que a resposta de Seifer abaixo é uma solução mais elegante para essa pergunta.

de lado
fonte
37
Mas lembre-se, se houver / houver linhas, após esse teste, você estará apontando para a primeira linha. Portanto, não salte uma linha acidentalmente.
2133 Matthew Flaschen
1
Bom ponto que o cursor (ponteiro) está apontando para a primeira linha
JohnMerlino
@ MatthewFlaschen, você está certo, para resolver o problema de pular a primeira linha, usei o do {...} while (rs.next);
Israelm 22/07
8
Você também pode ligar isBeforeFirst()para testar se há alguma linha retornada sem avançar o cursor e prosseguir normalmente.
SnakeDoc
528

Supondo que você esteja trabalhando com um recém-retornado ResultSetcujo cursor esteja apontando antes da primeira linha, uma maneira mais fácil de verificar isso é apenas chamar isBeforeFirst(). Isso evita a necessidade de rastrear novamente se os dados devem ser lidos.

Conforme explicado na documentação , isso retornará false se o cursor não estiver antes do primeiro registro ou se não houver linhas no ResultSet .

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

 

Seifer
fonte
15
Obrigado, sim, eu sei, mas encontrei o mesmo problema e não estava satisfeito com a aparência de avançar para verificar e depois ler para trás. Eu pensei que esta solução mais simples beneficiaria outros que estão na mesma situação.
Seifer 26/07
5
Observe que, pelo menos para o DB2, o conjunto de resultados deve ser do tipo "rolável". Isso pode ser definido quando você cria a instrução a ser executada.
Laurence Dougal Myers
1
A resposta de Felype abaixo é mais completa
Tom Howard
A partir da documentação Oracle: Nota: O suporte para o método isBeforeFirst é opcional para ResultSets com um tipo de conjunto de resultados de TYPE_FORWARD_ONLY
emi-le
52

você sempre pode fazer o próximo na frente e apenas fazer uma verificação de loop post

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

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

Você normalmente faria algo assim:

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

Se você deseja relatar um conjunto vazio, adicione uma variável contando os itens lidos. Se você só precisa ler um único item, seu código é adequado.

kgiannakakis
fonte
16

Para ter certeza absoluta de que o conjunto de resultados está vazio ou não, independentemente da posição do cursor, eu faria algo assim:

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

Essa função retornará true se ResultSet estiver vazio, false se não ou lançará uma SQLException se esse ResultSet estiver fechado / não inicializado.

Felype
fonte
12

É melhor usar ResultSet.next () junto com a sintaxe do {...} while () para isso.

A chamada "verificar se há resultados" resulta em ResultSet.next () move o cursor para a primeira linha; portanto, use a sintaxe do {...} while () para processar essa linha enquanto continua a processar as linhas restantes retornadas pelo loop.

Dessa forma, você pode verificar se há resultados e, ao mesmo tempo, processar os resultados retornados.

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
fonte
8

De acordo com a resposta mais viável, a sugestão é usar "isBeforeFirst ()". Essa não é a melhor solução se você não tiver um "tipo somente encaminhamento" .

Existe um método chamado " .first () ". É menos exagero obter exatamente o mesmo resultado. Você verifica se há algo no seu "conjunto de resultados" e não avança o cursor.

A documentação declara: "(...) false se não houver linhas no conjunto de resultados ".

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

Você também pode chamar isBeforeFirst () para testar se há alguma linha retornada sem avançar o cursor, e prossiga normalmente. - SnakeDoc 2 / set / 14 às 19:00

No entanto, há uma diferença entre "isBeforeFirst ()" e "first ()". Primeiro, gera uma exceção se realizada em um conjunto de resultados do tipo "somente encaminhamento".

Compare as duas seções de lançamento: 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 ()

Ok, basicamente isso significa que você deve usar "isBeforeFirst" desde que tenha um tipo "forward forward". Caso contrário, é menos exagerado usar "first ()".

OddDev
fonte
1
Como é "menos exagero" obter exatamente o mesmo resultado? Parece-me que o objetivo de first () é mover o cursor para a primeira linha, se ainda não estiver lá (e retornar true, se for bem-sucedido). isBeforeFirst é apenas uma função puramente de diagnóstico e parece mais adequada aos propósitos do autor. Além disso, a maneira como first () é redigida, retorna verdadeira desde que esteja "em uma linha válida" ... o que é estranho, como se poderia pensar que seria redigido como "na primeira linha". Para mim, não vejo a vantagem de usar first () neste cenário, a menos que seu cursor tenha avançado e você queira trazê-lo de volta ao começo.
Jon
5

Isso funcionaria se você quiser ver se há alguma linha no conjunto de resultados sim.

Observe que next() sempre passa para a próxima linha; portanto, se você estiver planejando fazer alguma leitura do conjunto de resultados, precisará levar isso em consideração.

O uso usual com o ResultSet (ao simplesmente ler) é:

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

O que obviamente não funcionará corretamente se você next()já tiver invocado uma vez para verificar se o conjunto de resultados estava vazio, portanto, preste atenção. Embora existam métodos para "fazer backup", eles não são suportados para todos os tipos de conjuntos de resultados.

Nuoji
fonte
5

Esta é uma peça de leitura prática e fácil, acredito.

        if (res.next()) {
            do {

                // successfully in. do the right things.

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

isAfterLast() também retorna false para o conjunto de resultados vazio, mas como o cursor está antes da primeira linha, esse método parece mais claro.

Nick Warke
fonte
2
if(resultSet.first) {

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

Porque se ResultSet não tiver raw, então resultSet.firstretornará false.

user868927
fonte
Mas ele se move cursor para a primeira linha desnecessário, e pode confundir ainda mais o uso de ob objeto "reset" e pode perder dados
Tigran Babajanyan
Embora pareça melhor, ele não funcionará em um conjunto de resultados de cursor somente para frente.
eliteproxy
1

A melhor coisa a fazer é verificar a primeira linha para que, quando você pretende obter os dados, possa evitar o erro de pular uma linha. Algo como: if (! ResultSet.first ()) {System.out.println ("sem dados"); }

Anthony Oyovwe
fonte
1

Usando resultSet.next (), você pode obter facilmente o resultado, resultSet contendo qualquer valor ou não

ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next())
 //resultSet contain some values
else
 // empty resultSet
Ram72119
fonte
Não repita as respostas existentes.
James.garriss 13/03/2015
1
ResultSet result = stmt.executeQuery(sqlQuery);
if (!result.next())
    status = "ERROR";
else
    status = "SUCCESS";
Deepu Surendran
fonte
1

Eu tenho tentado definir a linha atual para o primeiro índice (lidando com chaves primárias). eu sugeriria

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

Quando o ResultSet é preenchido, ele aponta para antes da primeira linha. Ao configurá-lo para a primeira linha (indicada por rs.absolute(1)), ele retornará true, indicando que foi colocado com sucesso na linha 1 ou false, se a linha não existir. Podemos extrapolar isso para

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

que define a linha atual para a posição ie falhará se a linha não existir. Este é apenas um método alternativo para

while(rs.next()){
    //Code
}
Andrew
fonte
Qual é sua resposta?
CMedina 04/04
1

Eu criei o seguinte método para verificar se um ResultSet está vazio.

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

É muito importante ter as seguintes considerações:

O objeto CallableStatement deve ser configurado para permitir que o objeto ResultSet chegue ao final e volte ao topo.

TYPE_SCROLL_SENSITIVE : O objeto ResultSet pode mudar no final e voltar ao topo. Além disso, pode pegar as últimas alterações.

CONCUR_READ_ONLY : podemos ler os dados do objeto ResultSet, mas não podemos atualizar.

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

Acho que a maneira mais fácil de verificar o conjunto de resultados é via CollectionUtils, no pacote org.apache.commons.collections.CollectionUtils

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

Isso verificará a condição do conjunto de resultados nulo e vazio.

Para informações mais detalhadas, você pode consultar o seguinte documento. ColeçãoUtils

Mitul Maheshwari
fonte
1
ResultSet não é uma coleção.
Joachim Lous
1

Por que não usar 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

Para mim, verifique "se (rs.getRow ()! = 0)" parece funcionar muito bem.

stiebrs
fonte
0

você pode fazer algo assim

boolean found = false;

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

if (!found)
    System.out.println("No Data");
Mohamed EL-Shabrawy
fonte
1
MUITO complicado.
Jordaniac89
0
ResultSet rs = rs.executeQuery();
if(rs.next())
{
  rs = rs.executeQuery();
  while(rs.next())
  {
    //do code part
  }
}
else
{
  //else if no result set
}

É melhor executar novamente a consulta, porque quando chamarmos a if(rs.next()){....}primeira linha do ResultSet será executada e, depois dela while(rs.next()){....}, obteremos o resultado da próxima linha. Então, acho que a reexecução da consulta interna ifé a melhor opção.

Arpit Trivedi
fonte
5
-1 Esta não é uma opção melhor. Por que consultar o banco de dados duas vezes? E se os dados mudarem drasticamente entre as chamadas? Isso é um desperdício.
precisa saber é o seguinte
-2

Inicialmente, o objeto do conjunto de resultados (rs) aponta para o BFR (antes do primeiro registro). Uma vez que usamos rs.next (), o cursor aponta para o primeiro registro e o rs mantém "true". Usando o loop while, você pode imprimir todos os registros da tabela. Depois que todos os registros são recuperados, o cursor se move para ALR (Após o último registro) e será definido como nulo. Vamos considerar que existem 2 registros na tabela.

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

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

Em resumo, também podemos escrever a condição como while (rs.next ()).

Shiva
fonte
3
Seu loop while não terá a chance de operar na primeira linha retornada, o que parece uma falha um tanto fatal com essa abordagem. Há muitas sugestões acima que são melhores que esta.
Jules