Re:Obrigatoriedade de teste em ResultSet.next()[RESOLVIDO]

Boa noite, hombres e muchachas

Estou com a seguinte dúvida: em um ResultSet retornado por Statement.executeQuery() é necessário percorrer com while() ou testá-lo com if()? Ainda que o result só tenha um registro?


                 if (ff.equals("2210")||ff.equals("2211")) {

                            Statement stmEmpresa = conn.createStatement();
                            ResultSet rsEmpresa = null;
                            rsEmpresa = stmEmpresa.executeQuery("SELECT emp_plano FROM folha.Empresa WHERE fab_matricula='"+matricula+"'");
                            
                            while(rsEmpresa.next()){  //ISSO É NECESSÁRIO?  por que não simplesmente "rsEmpresa.next()"?

                                if(ff.equals("2210") && rsEmpresa.getString(1).equals("2")){

                                      ff_sap = "9533";

                                }else if(ff.equals("2210") && rsEmpresa.getString(1).equals("3")){

                                      ff_sap = "P532";

                                }else if(ff.equals("2211") && rsEmpresa.getString(1).equals("2")){

                                      ff_sap = "9535";

                                }else if(ff.equals("2211") && rsEmpresa.getString(1).equals("3")){

                                      ff_sap = "P534";

                                }
                            
                            valor = rs.getString(7).replace(".", "");

                            }

                            rsEmpresa.close();
                            stmEmpresa.close();

                        }  else {

                            valor = rs.getString(7).replace(".", "");
                            ff_sap = (String) arqv2.get(ff);
                        }

Pergunto isso porque quando tiro o teste ocorre uma exceção. A VM diz que o result está fechado! Como, se o result acabou de ser criado, o fecho no final, e sempre que preciso fazer a consulta, o instancio novamente?!

grato

Se você tem certeza que só vai retornar um registro, então pode usar if (rsEmpresa.next())

Oi,

Eu utilizaria o while. Não vejo nenhum motivo para não usa-lo.

E um outro grande detalhe, fecharia o Statement e o ResultSet dentro de um bloco finally{}.

Só assim você irá garantir de que seu Result é mesmo fechado.

Tchauzin!

Bom dia,

Sim, romarcio, retorna apenas um único registro sempre. Minha dúvida é o porquê que só com teste o result.Next() funciona sem exception.

E por que o result não seria fechado normalmente fora do teste e fora do finally? Devo simplesmente abstrair isso? A primeira vista, não vejo muita lógica(creio que por ignorar como o método next funciona).

Resumindo: minha dúvida é por que não posso fazer simplesmente assim:


             rsEmpresa.next(); //já que sempre retorna um único registro
                    (...)
             rsEmpresa.close();  
             stmEmpresa.close();  

valew, caras

abraço

Quando o ResultSet é criado o cursor está posicionado antes do primeiro registro do resultado. Se você tem certeza que sempre haverá um registro no resultado, basta chamar next() uma única vez, e você estará posicionado no registro. O problema é esse “sempre”. Você não pode confiar demais no estado do banco de dados para que sua aplicação funcione. Se a consulta não retornar registro algum, mesmo que isso configure uma situação de erro é interessante você tratar essa situação, por isso você deve testar se a chamada a next() posicionou você em um registro de fato.

Para fechar o ResultSet, você não precisa fazer isso dentro do if, mas deve fazer em bloco finally como boa prática, pois se ocorrer uma exceção antes do comando close() do ResultSet e ele estiver fora de um bloco finally, close() não será chamado e o cursor ficará aberto no banco de dados.

certo, rmendes08. Boa explicação. Mas o interessante é que:

                       1- tendo recorrido ao banco, no registro onde é emitida a exceção, verifiquei que realmente só tem um registro, 
                       2- a exceção ocorre no next(), dizendo que o result está fechado, mas como, se ele acaba de ser criado?
                       3- no registro anterior, a execução se dá normalmente.

:frowning:

valeu!

abraço

Cara, posta o código que dispara a exceção, só assim pra saber o que está errado.

É o mesmo que está aí em cima, mas sem o while().


    if (ff.equals("2210")||ff.equals("2211")) {  
      
               Statement stmEmpresa = conn.createStatement();  
               ResultSet rsEmpresa = null;  
               rsEmpresa = stmEmpresa.executeQuery("SELECT emp_plano FROM folha.Empresa WHERE fab_matricula='"+matricula+"'");  
                 
               rsEmpresa.next()   // <----- Exceção(ResultSet fechado)
      
                   if(ff.equals("2210") && rsEmpresa.getString(1).equals("2")){  
      
                         ff_sap = "9533";  
      
                   }else if(ff.equals("2210") && rsEmpresa.getString(1).equals("3")){  
      
                         ff_sap = "P532";  
      
                   }else if(ff.equals("2211") && rsEmpresa.getString(1).equals("2")){  
      
                         ff_sap = "9535";  
      
                   }else if(ff.equals("2211") && rsEmpresa.getString(1).equals("3")){  
      
                         ff_sap = "P534";  
      
                   }  
                 
               valor = rs.getString(7).replace(".", ""); 
      
               rsEmpresa.close();  
               stmEmpresa.close();  
      
           }  else {  
      
               valor = rs.getString(7).replace(".", "");  
               ff_sap = (String) arqv2.get(ff);  
           }  

grato

Posta o código do jeitinho que você está executando, e coloca também a stack trace, com certeza você está indo pelo caminho errado. Não há como o método saber se ele está sendo chamado em uma linha vazia ou dentro de um comando if, portanto, o seu problema não é esse. A minha suspeita é que a query não retorna resultado, e quando você usa o if, ou o while o código é desviado para um trecho onde não acontece o erro. Posta a stacktrace.

Mas isso você não pode fazer:

rsEmpresa.next()  {   // <----- Exceção(ResultSet fechado)  
    
               if(ff.equals("2210") && rsEmpresa.getString(1).equals("2")){    
    
                     ff_sap = "9533";    
    
               }else if(ff.equals("2210") && rsEmpresa.getString(1).equals("3")){    
    
                     ff_sap = "P532";    
    
               }else if(ff.equals("2211") && rsEmpresa.getString(1).equals("2")){    
    
                     ff_sap = "9535";    
    
               }else if(ff.equals("2211") && rsEmpresa.getString(1).equals("3")){    
    
                     ff_sap = "P534";    
    
               }    

Assim pode:

rsEmpresa.next();  
if(ff.equals("2210") && rsEmpresa.getString(1).equals("2")){    
    ff_sap = "9533";    
}else if(ff.equals("2210") && rsEmpresa.getString(1).equals("3")){    
    ff_sap = "P532";    
}else if(ff.equals("2211") && rsEmpresa.getString(1).equals("2")){    
    ff_sap = "9535";    
}else if(ff.equals("2211") && rsEmpresa.getString(1).equals("3")){    
    ff_sap = "P534";   
}

opa! Sim claro! ignore o bloco. Foi erro no copiar/colar. vou corrigir código aí em cima, mas o problema é o mesmo.

StackTrace:


        com.ibm.db2.jcc.c.SqlException: [ibm][db2][jcc][10120][10898] Operação inválida: result set está fechado.
        at com.ibm.db2.jcc.c.wf.mb(wf.java:3193)
        at com.ibm.db2.jcc.c.wf.j(wf.java:3164)
        at com.ibm.db2.jcc.c.wf.getString(wf.java:788)
        at SAPHelper.HR.HRHelper.hrFichaFinanceira(HRHelper.java:5288)
        at SAPHelper.HR.HRHelper.main(HRHelper.java:5650)

grato

Tem outra coisa errada no código:

Statement stmEmpresa = conn.createStatement();    
ResultSet rsEmpresa = null;    
rsEmpresa = stmFabasa.executeQuery("SELECT emp_plano FROM folha.Empresa WHERE fab_matricula='"+matricula+"'");   

Você cro]iou o Statement stmEmpresa mas passou para o resultset o (stmFabasa e não o stmEmpresa) rsEmpresa = stmFabasa.executeQuery.

opa! mais um erro de post. ignora isso tmb. Corrigindo o código…

valeu.

[quote=tiagosarj]opa! mais um erro de post. ignora isso tmb. Corrigindo o código…

valeu.[/quote]
Mas entao, o erro ainda continua?
Tiago recomento pelas boas orientações em programação que nao utilize apenas rsEmpresa.next(); pois como você está fazendo uma consulta no banco você está sujeito a não retornar algum registro, como é só com um registro pra voltar recomento que utilize o if(rsEmpresa.next()){
}

se caso não retornar algum registro o sistema vai continuar linha por linha e vai dar erro por quando ele tentar rsEmpres.getString(1) nao ter nada para pegar e vai pular para o Exception e tambem é por isso que recomendaram colocar o close no finally pois se ir para o Exception mesmo assim o resultset sera fechado :lol:

A verificação se existe registro é sempre bem vinda :slight_smile:

Sim, sim, si. Era só uma dúvida. Não estava entendendo porque o result estava fechado se tinha acabado de ser criado. Sei que, quando não existe nenhum registro a ser retornado, o result estará fechado. Abri o tópico porque no momento que era emitida a exceção, havia registro. Ao menos eu achava que havia :oops: . Tinha um outro teste no código que fazia com que entrasse no trecho em um momento que eu estava ignorando. E sob essas condições, realmente não existia registro algum. Como não coloquei todo o código aqui, e isso não seria pertinente, vocês não puderam enxergar, e em verdade nem poderiam sem o banco.

grato a todos

abraço

[quote=tiagosarj]Sim, sim, si. Era só uma dúvida. Não estava entendendo porque o result estava fechado se tinha acabado de ser criado. Sei que, quando não existe nenhum registro a ser retornado, o result estará fechado. Abri o tópico porque no momento que era emitida a exceção, havia registro. Ao menos eu achava que havia :oops: . Tinha um outro teste no código que fazia com que entrasse no trecho em um momento que eu estava ignorando. E sob essas condições, realmente não existia registro algum. Como não coloquei todo o código aqui, e isso não seria pertinente, vocês não puderam enxergar, e em verdade nem poderiam sem o banco.

grato a todos

abraço[/quote]

É nomal, vai se acostumando que isso acontece direto, olha a garf que eu cometi nesse post
http://www.guj.com.br/java/249544-resolvido-c-observacao-como-abrir-arquivo-ppt-pelo-java-
la no finalzinho, as cinco ultimas mensagens rsrsr

Ahá! Se em determinadas condições não existe registro isso só mostra que é necessário fazer o teste!

Mesmo que presumidamente sempre havera dados, é uma boa prática sempre provar aquilo que se presume. Eu simplificaria da seguinte maneira:

ResultSet rs = ........
if (!rs.next()) {
     throw new AlgumaException("Dados inconsistentes, nao existe o registro tal");
}

// Aqui continua a vida normal. Agora sim é garantido que o resultset esta posicionado no primeiro registro
vari = rs.getString("Campo");
...
...

Ahá! Se em determinadas condições não existe registro isso só mostra que é necessário fazer o teste!

Mesmo que presumidamente sempre havera dados, é uma boa prática sempre provar aquilo que se presume. Eu simplificaria da seguinte maneira:

[code]
ResultSet rs = …
if (!rs.next()) {
throw new AlgumaException(“Dados inconsistentes, nao existe o registro tal”);
}

// Aqui continua a vida normal. Agora sim é garantido que o resultset esta posicionado no primeiro registro
vari = rs.getString(“Campo”);


[/code][/quote]
Ué… mas se ele nao tiver registro o sistema deve parar por ali…
será que não seria melhor assim…

if(rs.next()){ //aqui faz o codigo que ja tem }else{ //Se não ouver dados ele executa isso int i = JOptionPane.showConfirmDialog(null, "Deseja mesmo visualizar o resultado da busca?"); if(i == 0){ JOptionPane.showMessageDialog(null, "Hááá pegadinha do malandro, não tem dados não."); }else if(i==1){ JOptionPane.showMessageDialog(null, "Sorte sua, afinal não foram encontrados dados."); }else if(i==2){ JOptionPane.showMessageDialog(null, "Se era pra cancelar porque fez a pesquisa eim seu calango branco."); } }

Ahn han! Dá pra confiar não! testando sempre a partir de agora…

:smiley:

Ahn han! Isso acontece com os erros mais banais, por falta de atenção. Que não nos aconteça quando o tempo for escasso, e quando não, que enxerguemos a tempo!

valeu, caras

abraço