Problema com WHILE

13 respostas
acbucard
Gente, estou tentando fazer um cálculo com os dados provenientes do banco, só que está dando erro. A parte do sql acredito estar certo pois a parte do try/catch funciona corretamente. O problema está sendo no total. Meu código é:
try{
         Diaria.executarSQL("select * from controledia where dataAtend="+ano+"-"+mes+"-"+dia);
         while(Diaria.resultset.next()){
           Total=Diaria.resultset.getDouble("totalS");
           
            Diario+=Total;
            Diaria.resultset.next();
          }
          }catch(Exception erro){
                JOptionPane.showMessageDialog(null,"Não deu pra calcular");
                }
        JOptionPane.showMessageDialog(null,"Valor do dia = R$"+Diario);
Nesse JOptionPane aparece o valor zerado.

Obrigada desde já

13 Respostas

leocantanhede

Pela pedaço de código postado, gostaria de saber se Diario é classe ou variável, e se for variável gostaria de saber se ela esta declarada e iniciada fora do try catch, se for do tipo double, terá que fazer um parse para String para ser exibido no JOptionPane.

BrunoFurtado

Opa,

Consegue postar teu método completo?

Faço essas considerações:

try{
   // aqui vc esta utilizando Statement, isso é incorreto pois pode gerar falhas de segurança
   // o correto seria utilizar PreparedStatement...
   Diaria.executarSQL("select * from controledia where dataAtend="+ano+"-"+mes+"-"+dia);

   while(Diaria.resultset.next()){
      // nome de variaveis, em Java, devem iniciar com letra minuscula (boas normas...)
      Total=Diaria.resultset.getDouble("totalS");
      
      //imprime na Console o valor, para verificacao se vem 0
      System.out.println("Valor ResultSet: " + Diaria.resultset.getDouble("totalS"));     

      //imprime na Console o valor, para verificacao se vem 0
      Diario+=Total;
      System.out.println("Diario: " + Diario);     
      
      // linha desnecessaria pois o while á faz isso automaticamente
      // assim, o resultSet estava pulando um valor...
      // Diaria.resultset.next();
   }
} catch(Exception erro) { 
   JOptionPane.showMessageDialog(null,"Não deu pra calcular");
}
   
JOptionPane.showMessageDialog(null,"Valor do dia = R$"+Diario);
A

Carinha, alguns comentários:

Esse SQL montado do jeito que você tá fazendo, com select concatenado é feio pra danar… o certo seria usar parametrização por data. Mas não sei o que tem dentro dessa classe Diaria, então pode não ser culpa sua, mas sim da criatura que criou essa classe antes…

Mas vê se esse Diaria tem algum método do tipo “prepararStatementSQL”… que gera um PreparedStatement e daí você faz um negócio mais ou menos assim… (e pedindo desculpas se tem algum código errado, porque tou fazendo de cabeça, sem testar).

PreparedStatement stmt = Diaria.prepararStatementSQL("select * from controledia where dataAtend = ?");
Calendar c = calendar.getInstance();
c.setYear(ano);
c.setMonth(mes);
c.setDay(day);
stmt.setDate(new Date(Calendar.getTimeInMillis));
ResultSet rs = stmt.executeQuery();

Mas, no seu código especifico, o problema é que você está chamando o next duas vezes: uma na condição e ooutra dentro do While. Tira o Diaria.resultset.next depois do += Total, dentro do while que o bicho funciona.

acbucard
Bem... o código é esse:
String data, dia, mes, ano;
                data=txtData.getText();
                dia=data.substring (0,2);
                mes=data.substring(3,5);
                ano=data.substring(6,10);
                Double Diario, Total;
                Diario=0.0;
                Total = 0.0;
                String total;

            try{
                 Diaria.executarSQL("select * from controledia where dataAtend="+ano+"-"+mes+"-"+dia);
            while(Diaria.resultset.next()){
                total=Diaria.resultset.getString("totalS");
                
                Total=Double.parseDouble(total);
                Diario=Diario+Total;
             }
                }
                catch(Exception erro){
                    JOptionPane.showMessageDialog(null,"Não deu pra calcular");
                }

leocantanhede, eu já não teria concatenado ao adicionar o texto antes?

BrunoFurtado, eu acabei me perdendo no lance de maiúsculas e minúscula, pois antes estava de burrice jogando na String total o valor do banco e depois transformando em double Total, entende?
O lance de pular um dado, eu imaginei, mas no desespero tentei isso tabém!

A

Outro comentário: o select com concatenação da data pode ser a origem do seu problema: faça o seguinte teste -
Em vez de

Diaria.executarSQL("select * from controledia where dataAtend="+ano+"-"+mes+"-"+dia);

experimente fazer isso:

String sql  ="select * from controledia where dataAtend="+ano+"-"+mes+"-"+dia;
System.out.println(sql);
Diaria.executarSQL(sql);

E daí experimente rodar o sql que saiu no System.out diretamente no banco e vê o que acontece…

BrunoFurtado

abmpicoli:
Outro comentário: o select com concatenação da data pode ser a origem do seu problema: faça o seguinte teste -
Em vez de

Diaria.executarSQL("select * from controledia where dataAtend="+ano+"-"+mes+"-"+dia);

experimente fazer isso:

String sql  ="select * from controledia where dataAtend="+ano+"-"+mes+"-"+dia;
System.out.println(sql);
Diaria.executarSQL(sql);

E daí experimente rodar o sql que saiu no System.out diretamente no banco e vê o que acontece…

É…
Na realidade, se fosse pra fazer a parada de acordo com as “boas normas”…
O correto seria este método receber um parâmetro do tipo Calendar, Date, ou uma String com o formato correto.
E ai, utilizar o PreparedStatement, passando uma String formatada com o valor correto.

Esse código tá meio “sinistro”…rs

É importante verificar no seu banco de dados qual a formatação de data (dd-mm-yyyy ou mm/dd/yy ou outras).
Para isso, basta fazer um “select * from controledia” e ver qual é o retorno do campo dataAtend.
Atenção tb, pois as datas dos meses de 1 a 9 podem necessitar ser 01, 02, 03…

O “Diaria” é uma DaoFactory, correto?

acbucard

abmpicoli
Obrigada!
Agora funcionou!! \o/

Agora mais uma coisinha!

Eu precisava que essa data fosse enviada para uma classe, onde estão os parâmetros do relatório.
Tentei criar uma label na marra mas não funcionou!
Tentei na classe o public static javax.swing.JLabel lblData;
e nessa tela o relatorio.totalDia.lblData.setText(txtData.getText());

Qual seria o melhor jeito de fazer isso?

acbucard

BrunoFurtado, pois então!
Esse código foi meu professor que me passou.
Esse Diaria foi é um objeto da classe ConexaoBD que é onde ele criou a conexao com o BD.

acbucard

BrunoFurtado:
É…
Na realidade, se fosse pra fazer a parada de acordo com as “boas normas”…
O correto seria este método receber um parâmetro do tipo Calendar, Date, ou uma String com o formato correto.
E ai, utilizar o PreparedStatement, passando uma String formatada com o valor correto.

Esse código tá meio “sinistro”…rs

É importante verificar no seu banco de dados qual a formatação de data (dd-mm-yyyy ou mm/dd/yy ou outras).
Para isso, basta fazer um “select * from controledia” e ver qual é o retorno do campo dataAtend.
Atenção tb, pois as datas dos meses de 1 a 9 podem necessitar ser 01, 02, 03…

O “Diaria” é uma DaoFactory, correto?

Pois é, estou usando o MySql e ele retorna yyyy-MM-dd, e quando pesquisei, me disseram que não seria legal mexer no formato do banco, e o único modo que eu consegui entender pra “formatar” a data foi esse. =(

A

acbucard:
abmpicoli
Obrigada!
Agora funcionou!! \o/

Agora mais uma coisinha!

Eu precisava que essa data fosse enviada para uma classe, onde estão os parâmetros do relatório.
Tentei criar uma label na marra mas não funcionou!
Tentei na classe o public static javax.swing.JLabel lblData;
e nessa tela o relatorio.totalDia.lblData.setText(txtData.getText());

Qual seria o melhor jeito de fazer isso?

Ô, zifia, num entendi nadinha do que você quer fazer… Que classe é essa que você quer colocar os parâmetros? Bom, tipicamente, é legal seguir o design pattern “Model”, “View”,“Controller” em aplicações desktop. Então, criar um label a partir do DAO é dar tiro no pé. O certo é que o controller chame o método do DAO e o DAO retorne o valor. Daí o controller passa para a view. Entendeu?

Por exemplo, na minha aplicação eu tenho a classe CertuniDoAlexander, que é meu “controller”. Aí, no meu CertuniDoAlexander eu teria um método “exibirRelatório()”. O método “exibirRelatorio()” então chamaria o seu DAO e receberia esse valor que você está calculando. Daí dentro do método “exibirRelatorio” eu chamo algo do tipo “minhaInstanciaDeRelatorio.setMeuValor( xxx)”. E aí quem é responsável por saber aonde esse dado é exibido é responsabilidade da classe da minhaInstanciaDeRelatorio.

Aí, no seu relatório, no método setMeuValor, você atualiza o label do formulário do jeito que achar mais conveniente.

Entendeu?

acbucard

Bem, deixe-me tentar explicar denovo.
Essa dúvida "Problemas com WHILE" surgiu quando eu estava montando um JInternalFrame onde o usuário digita a data que ela quer que seja gerado relatório e ao
clicar em gerar, o programa, calcula o valor total gerado naquele dia e em seguida o relatório com as informações dos serviços prestados.

Esse while foi usado nesse cálculo.

Daí depois disso, eu chamo a classe totalDia, onde estão as informações que preencherão meu relatório.
public totalDia() {
  try
  {
      conexao.conectarBD();
      conexao.executarSQL("SELECT * from controledia where dataAtend='"+ano+"-"+mes+"-"+dia+"'");
      JRResultSetDataSource jrRS = new JRResultSetDataSource(conexao.resultset);
      JasperPrint jasperPrint = JasperFillManager.fillReport("./src/relatorio/totalDia.jasper", new HashMap(), jrRS);
      JasperViewer.viewReport(jasperPrint);
  } catch (Exception erro){
             JOptionPane.showMessageDialog(null,"deu erro ="+erro);
   }
}

  public static void main (String args[])
  {
    new totalDia();
  }

}

Só que eu preciso que a data digitada no JInternalFrame seja enviada para essa classe acima para servir de parâmetro para a query.
Entende?

Tentei mandar como variável, só que diz que não pode pois uma variável é não estática, se quando eu crio, o faço como estática dá outro erro que não me recordo e como
na tela principal eu coloquei o nome do usuário logado como lbl, pensei que nesse caso aqui também pudesse ser uma boa idéia!

A

public totalDia(String ano, String mes, String dia) { …

}

Aí no seu teste você coloca new totalDia(ano, mes,dia);

E se você quiser pegar esses métodos depois, guarda essas informações em campos locais e coloque métodos públicos para recuperar a informação.

acbucard

abmpicoli
Agradeço a sua ajuda!
Acabou que ao invés de criar uma outra classe para preencher o relatório, criei o método no próprio jInternalFrame!

Criado 1 de fevereiro de 2012
Ultima resposta 2 de fev. de 2012
Respostas 13
Participantes 4