For não funciona perfeitamente com variáveis globais

26 respostas
programaçãojavamysql
C

Gente, boa tarde a todos!

Eu não sei mais o que fazer, e preciso de uma ajuda. Estou criando um programa que gera relatórios com informações trazidas de uma base de dados do banco, mas eu não sei o que acontece, que o programa só retorna todos os valores se eu utilizar variáveis internas da função.
Qualquer variável externa inserida executa o loop apenas uma vez, e eu PRECISO utilizar as informações retornadas em outras finalidades.

Uma breve explicação do código:

*Existe uma base de dados, com duas colunas, “contagem” (que armazena um contador crescente) e “duração” (que armazena em string tempo cronometrado);

Existe um trecho de código em comentário. Esse trecho de código é o que funciona, somente com as variáveis internas. O trecho sem comentar, é o trecho que não funciona o loop perfeitamente

public void recuperaligacoes() {
/RECUPERA O REGISTRO DE LIGAÇÕES DA TABELA/

recuperacontagem(); // traz o valor máximo da coluna "contagem"

        try {
            int cast, resultado = getResultado(), i, num = getResultado();
            String resultadotabela[] = new String[getResultado()];
            System.out.println("Contagem \t Tempo \n");
            /* for (i = 0, cast = 1; i <= num && cast <= resultado; i++, cast++) {

                String sql = "SELECT duracao from ligacao where contagem ='" + cast + "';";
                PreparedStatement stmt = connection.prepareStatement(sql);
                rs = stmt.executeQuery();
    
                while (rs.next()) {
                    resultadotabela[i] = rs.getString("duracao");
                    System.out.println(cast + "\t\t" + resultadotabela[i] + "\n");
                    stmt.close();
                }

            }*/

            for (cast = 1; cast <= resultado; cast++) {
                String sql = "SELECT duracao from ligacao where contagem ='" + cast + "';";
                PreparedStatement stmt = connection.prepareStatement(sql);
                rs = stmt.executeQuery();
                for (i = 0; i <= num; i++) {
                    while (rs.next()) {
                        resultadotabela[i] = rs.getString("duracao");
                        System.out.println(cast + "\t\t" + resultadotabela[i] + "\n");
                        stmt.close();
                    }
                    teste[i]=resultadotabela[i]; //variável teste é global, parametrizada com o campo "resultado", que traz o valor máximo da coluna "contagem"
                    System.out.println(teste[i]);
                }
            }

        } catch (Exception e) {

        }

    }

Por favor, alguém poderia me dar uma luz nesse problema, pois não sei mais o que fazer, nem como jogar o resultado para uso em outra função.

Obrigada desde já

26 Respostas

V

tem 2 coisas erradas neste trecho,
1 - Você não precisa do for externo simplesmente declarar um int i=0 e dentro do While dar i++;
2 - stmt.close(); tem que ser chamado de fora do while, você esta mandando fechar a conexão repetidas vezes, sinceramente eu nem mesmo sei o que isso pode ocasionar.

V

Nunca faça um for de executeQuery(), você esta criando varias conexões seguidas, isso deixara o pc onde esta seu banco de dados lento e muito provavelmente ele não retornará resultado.

Você poderia substituir essa Query por
"SELECT duracao from ligacao where contagem Between 1 and " + resultado +" '; "

C

Haja coisa errada! hahaha

Eu arrumei esses pontos que você mencionou, e agora está muito melhor, obrigada! Mas ainda tenho problemas…

  • a String resultadotabela não é populada se declarada fora do try{
  • o sistema simplesmente ignora a string teste, e o s.o.p. dela

public void recuperaligacoes() {
//RECUPERA O REGISTRO DE LIGAÇÕES DA TABELA

String resultadotabela[] = new String[getResultado()];
    recuperacontagem();

    try {
        int cast, resultado = getResultado(), i=0, num = getResultado();
        
        System.out.println("Contagem \t Tempo \n");

        do{
            String sql = "SELECT duracao from ligacao where contagem between 1 and'" + resultado + "';";
            PreparedStatement stmt = connection.prepareStatement(sql);
            rs = stmt.executeQuery();
            //for (i = 0; i <= num; i++) {
            
                while (rs.next()) {
                    resultadotabela[i] = rs.getString("duracao");
                    System.out.println(i + "\t\t" + resultadotabela[i] + "\n");
                    i++;
                    
                }
                
                
                teste[i]=resultadotabela[i];
                System.out.println(teste[i]);

                stmt.close();
           }while(i>resultado);
        //}

    } catch (Exception e) {

    }

}
S

Qual a necessidade desse do while?

P

NUNCA faças isto… Se ocorrer um erro não irás saber.

C

Bom, a ideia é executar um loop que preenche um vetor com o select do banco…rs

Está ruim?

C

pmlm, eu só coloquei assim pq:

  1. o programa me obrigou a colocar um catch;
  2. eu não sei o que colocar dentro desse catch…rs
S

É que você tem 2 laços um do-while mais externo e dentro dele tem um while que alimenta seu array.
Pra que serve o do-while externo?

Você está chamando o método getResultado() 3 vezes, o que esse método retorna?

Dá uma olhada se assim não atende sua necessidade:

// RECUPERA O REGISTRO DE LIGAÇÕES DA TABELA
public void recuperaligacoes() throws SQLException {
    int resultado = getResultado(); // o que esse método retorna? resultado do que?
    String resultadotabela[] = new String[resultado];
    recuperacontagem(); // o que esse método faz?
    System.out.println("Contagem \t Tempo \n");
    String sql = "SELECT duracao from ligacao where contagem between 1 and ? ";
    PreparedStatement stmt = connection.prepareStatement(sql);
    stmt.setInt(1, resultado);
    ResultSet rs = stmt.executeQuery();
    int i = 0;
    while (rs.next()) {
        resultadotabela[i] = rs.getString("duracao");
        System.out.println(i + "\t\t" + resultadotabela[i] + "\n");
        i++;
    }
    stmt.close();
}
C

Então… antes de ser um do-while, era um for…

Aí um membro da comunidade respondeu que estava abrindo mtas instâncias, e o ideal pro caso seria um do-while… foi o que eu fiz… hahaha

O getResultado() traz o resultado da leitura da query "“SELECT MAX(contagem) as contagem from ligacao;”;

Vou colocar o código aqui:

public int recuperacontagem() {

Codigos co = new Codigos();
    String sql = "SELECT MAX(contagem) as contagem from ligacao;";

    try {
        PreparedStatement stmt = connection.prepareStatement(sql);
        rs = stmt.executeQuery();
        while (rs.next()) {

            setResultado(rs.getInt("contagem"));

            co.setContaparada(getResultado()); //contaparada pega o valor do resultado, e joga em outro método, que alimenta um contador automático
        }

    } catch (SQLException e) {

        //Saída de erro para o usuário.
        JOptionPane.showMessageDialog(null,
                "Houve um erro ao selecionar os dados!",
                "ERRO!",
                JOptionPane.ERROR_MESSAGE);

        //Saída de erro para o programador.
        System.out.println("ERRO:(LigacaoDAO.recuperacontagem)" + e.getMessage());
    }
    System.out.println("valor de resultado puxado da base: " + getResultado());
    //Retorna o resultado da execução SQL.

    try {
        if (getResultado() == 3) {
            sql = "DELETE from ligacao;";
            PreparedStatement stmt = connection.prepareStatement(sql);
            rs = stmt.executeQuery();;
            stmt.close();
        }

    } catch (SQLException e) {

        //Saída de erro para o usuário.
        JOptionPane.showMessageDialog(null,
                "Houve um erro ao selecionar os dados!",
                "ERRO!",
                JOptionPane.ERROR_MESSAGE);

        //Saída de erro para o programador.
        System.out.println("ERRO:(LigacaoDAO.limpeza)" + e.getMessage());
    }
    System.out.println("valor de resultado puxado da base: " + getResultado());
    //Retorna o resultado da execução SQL.{

    return resultado;

}

engraçado é que quanto mais olho, mais começo a achar que meu código está mais zoneado que o Bahamas…rs

V

Quando eu disse para não usar o FOR na verdade eu queria dizer para não usar uma estrutura de repetição.

C

Olha eu entendendo errado! hahaha

desculpa @Vinicius_Salles >.<

C

Outra coisa: tentei o seu código.

Deu o erro abaixo:

Exception in thread “AWT-EventQueue-0” java.lang.RuntimeException: Uncompilable source code - unreported exception java.sql.SQLException; must be caught or declared to be thrown

S

Que bom que percebeu, já é meio caminho pra melhorar.

O método recuperacontagem() já faz isso, qual a necessidade de ter um setResultado() e getResultado()?

Veja:

public String[] recuperaLigacoes() throws SQLException {
    int contagem = recuperaContagem();
    String ligacoes[] = new String[contagem];
    String sql = "SELECT duracao from ligacao where contagem between 1 and ? ";
    PreparedStatement stmt = connection.prepareStatement(sql);
    stmt.setInt(1, contagem);
    ResultSet rs = stmt.executeQuery();
    int i = 0;
    while (rs.next()) {
        ligacoes[i] = rs.getString("duracao");
        i++;
    }
    return ligacoes;
}

public int recuperaContagem() throws SQLException {
    int contagem = 0;
    String sql = "SELECT MAX(contagem) as contagem from ligacao;";
    PreparedStatement stmt = connection.prepareStatement(sql);
    ResultSet rs = stmt.executeQuery();
    if (rs.next()) {
        contagem = rs.getInt("contagem");
    }
    return contagem;
}

E porque se chama getResultado() e setResultado()

C

O método recuperacontagem() já faz isso, qual a necessidade de ter um setResultado() e getResultado()?

Pelo visto, nenhuma… haha Achei que era necessário, por conta de encapsulamento.

Que bom que percebeu, já é meio caminho pra melhorar.

Como se nota, eu sou meio crua em Java com BD…rs Já criei umas 8 versões do código todo, tentando buscar melhoria, mas sinto que em algumas coisas eu estou bem presa…rs

C

eu coloquei a codificação que vc publicou no meu tópico, e dá erro!

Eu não entendo pq, visto que é basicamente a mesma coisa, só que organizado, e fora de um try…catch.

Ele dá esse erro aqui
Exception in thread “AWT-EventQueue-0” java.lang.ArrayIndexOutOfBoundsException: 0

Pelo que li, esse erro acontece quando o array não tem parâmetro, mas os parâmetros estão setados!

Não to entendendo mais nada… :frowning:

S

Seu array está vazio, aí não tem como acessar a posição 0.
Da uma depurada no código.

C

eu olhei o código aqui, ele dá erro pq fica pedindo pra ser circundado com try-catch, que foi justamente o que saiu!

:woman_shrugging:t4:

S

É como é que aconteceu ArrayIndexOutOfBounds se seu código está com erro de compilação e nem executa?
Se executou, não tem erro de compilação.

C

Ele executa até o while, aí dá o erro de Array

public String[] recuperaLigacoes() throws SQLException {
    int contagem = recuperaContagem();
    String ligacoes[] = new String[contagem];
    String sql = "SELECT duracao from ligacao where contagem between 1 and ? ";
    PreparedStatement stmt = connection.prepareStatement(sql);
    stmt.setInt(1, contagem);
    ResultSet rs = stmt.executeQuery();
    int i = 0;
    while (rs.next()) {
        ligacoes[i] = rs.getString("duracao");
        i++;
    }
    return ligacoes;
}

Poderia então ser bug de compilador?

V

mostra qual é o erro que aparece.

C

Exception in thread “AWT-EventQueue-0” java.lang.ArrayIndexOutOfBoundsException: 0
at dao.Ligacao.recuperaligacoes(Ligacao.java:103) (é a linha identificada abaixo)

at chronos.Relatorio.relatorio_diaActionPerformed(Relatorio.java:103)
at chronos.Relatorio.access$000(Relatorio.java:18)
at chronos.Relatorio$1.actionPerformed(Relatorio.java:54)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6533)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6298)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
V

Isso acontece quando você tenta acessar uma posição que não existe no seu vetor.

Você esta declarando um vetor com tamanho definido para receber um resultado de uma busca, mas não tem como saber quantos registros vão ser retornados pelo seu Banco de Dados, então não da pra usar um vetor para receber os dados que estão sendo buscados.

Vai ter que criar um ArrayList.

ArrayList<String> ligacoes = new ArrayList<String>();

dentro do While você cria uma String para receber o resultado e depois adiciona na ArrayList.

while (rs.next()) {
    String resultado = new String();
    resultado= rs.getString("duracao");
    ligacoes.add(resultado);
}
S

Seu array está sendo inicializado com tamanho 0.

C

Coloquei em arraylist, e o resultado está saindo dessa forma:

Contagem Tempo

0 [00:00:01]

1 [00:00:01, 00:00:02] // deveria aparecer só o 00:00:02

2 [00:00:01, 00:00:02, 00:00:03] // deveria aparecer só o 00:00:03

3 [00:00:01, 00:00:02, 00:00:03, 00:00:05] // deveria aparecer só o 00:00:05

Como eu faço pra mostrar apenas o valor necessário?

@staroski então eu deveria inicializar o array como?

Sim, eu estou trabalhando com duas codificações pra mesma coisa agora, fazendo com arraylist, e com o array puro.

S

Pelo que entendi o seu método recuperaContagem() deveria retornar um número, que você usa como tamanho do array.
Mas se seu método retorna 0, você é que tem que analisar o que está errado.
Mas se você está usando uma lista, não precisa do array.

Fazendo o print somente do que você quer e não da lista inteira.

Acho que você tem que ficar mais em lógica, faz uns testes de mesa.
Você não vai aprender na tentativa e erro.

C

Pelo que entendi o seu método recuperaContagem() deveria retornar um número, que você usa como tamanho do array.
Mas se seu método retorna 0, você é que tem que analisar o que está errado.
Mas se você está usando uma lista, não precisa do array.

Ele retorna. Eu deixo dentro do método um sop que informa qual o valor que é retornado, e ele sempre retornou resultado e talz. O que pega é justamente na hora de preencher o array.

Fazendo o print somente do que você quer e não da lista inteira.

Ah ta, achei que era só colocar sop e pronto nesse caso.

Acho que você tem que ficar mais em lógica, faz uns testes de mesa.
Você não vai aprender na tentativa e erro.

Por mais incrível que possa não parecer, eu faço, eu analiso, eu tento na medida das minhas possibilidades. Inclusive eu mencionei que estava fazendo em array e lista, pra entender as diferenças, e poder adquirir mais conhecimento.

De qq forma, eu levei o meu código pra casa ontem a noite, e rodei na minha máquina. Mesmo com a questão da lista, o programa funcionou perfeitamente, o que me leva a crer que o problema é na máquina que eu operava o código…

Agradeço a todos pela ajuda, e sinto que deveria pagar uma cerveja pra cada um que me ajudou…rs

Criado 16 de março de 2018
Ultima resposta 23 de mar. de 2018
Respostas 26
Participantes 4