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?!
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();
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.
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.
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)
[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
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.
[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.
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…
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!