(RESOLVIDO) Erro ao gravar o valor do credito no banco

29 respostas
adsadilson

Bom dia pessoal estou com um probleminha ao salvar os valores de credito e debito dentro do banco aparece a seguinte mensagem alguem poderia me ajuda

org.postgresql.util.PSQLException: ERROR: invalid input syntax for type double precision: 150.000,00

at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1592)

at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1327)

at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:192)

at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451)

at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:336)

at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:282)

at view.JDialogEdiLivroCaixa.salvarLancamento(JDialogEdiLivroCaixa.java:280)

at view.JDialogEdiLivroCaixa.jbNovoActionPerformed(JDialogEdiLivroCaixa.java:219)

at view.JDialogEdiLivroCaixa.access$000(JDialogEdiLivroCaixa.java:21)
private static String formatarValor(String valor) {   
    DecimalFormat formatador = new DecimalFormat("##,##00.00");   
    String s = formatarValor(valor);   
    s = s.replace(',', '.');   
    return s;   
}  


    private void salvarLancamento() {
        java.sql.Connection con = null;
        try {
            con = Factory.ConnectionFactory.getConexaoMysql();
        } catch (SQLException ex) {
            Logger.getLogger(JDialogCadUsuario.class.getName()).log(Level.SEVERE, null, ex);
        }

        //Inserindo     os dados
        Date data = null;
        try {
            data = formatarData(this.txtdata.getText());
        } catch (ParseException ex) {
            System.out.println("erro ao formartar a data1" + ex);
        }
        String historico = this.txthistorico.getText();
        String credito = this.txtcredito.getText();
        String debito = this.txtdebito.getText();

        String sql = "insert into fluxocaixa (data_lanc,historico,credito,debito)values"
                + "('" + data + "','" + historico + "','" + credito + "','" + debito + "')";
        try {
            java.sql.Statement smt = con.createStatement();
            smt.executeUpdate(sql);
            System.out.println(sql);
            smt.close();
            con.close();
            JOptionPane.showMessageDialog(null, "Registro salvo com sucesso!!!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

esse é o codigo eu ate usei o metodo formatarValor mais nao consegui

29 Respostas

SandroSoftwares

problema: double só aceita .(ponto) para centavos:

invalid input syntax for type double precision: “150[size=18].[/size]000[size=12],[/size]00”

Marcelo_de_Andrade

Substitua todas a vírgulas por pontos para então armazená-los.

adsadilson

SandroSoftwares

agora eu usei o metodo formatarValor()
mais deu outro erro

xception in thread AWT-EventQueue-0 java.lang.StackOverflowError

at java.lang.String.(String.java:234)

at java.lang.StringBuffer.toString(StringBuffer.java:561)

at java.text.DecimalFormat.expandAffix(DecimalFormat.java:2039)

at java.text.DecimalFormat.expandAffixes(DecimalFormat.java:1979)

at java.text.DecimalFormat.applyPattern(DecimalFormat.java:2664)

at java.text.DecimalFormat.(DecimalFormat.java:435)

at view.JDialogEdiLivroCaixa.formatarValor(JDialogEdiLivroCaixa.java:249)

at view.JDialogEdiLivroCaixa.formatarValor(JDialogEdiLivroCaixa.java:250)

at view.JDialogEdiLivroCaixa.formatarValor(JDialogEdiLivroCaixa.java:250)

at view.JDialogEdiLivroCaixa.formatarValor(JDialogEdiLivroCaixa.java:250)

at view.JDialogEdiLivroCaixa.formatarValor(JDialogEdiLivroCaixa.java:250)

at view.JDialogEdiLivroCaixa.formatarValor(JDialogEdiLivroCaixa.java:250)

at view.JDialogEdiLivroCaixa.formatarValor(JDialogEdiLivroCaixa.java:250)
String historico = this.txthistorico.getText();
        String credito = formatarValor(this.txtcredito.getText());
        String debito = formatarValor(this.txtdebito.getText());

        String sql = "insert into fluxocaixa (data_lanc,historico,credito,debito)values"
                + "('" + data + "','" + historico + "','" + credito + "','" + debito + "')";
        try {
            java.sql.Statement smt = con.createStatement();
            smt.executeUpdate(sql);
            System.out.println(sql);
            smt.close();
            con.close();
            JOptionPane.showMessageDialog(null, "Registro salvo com sucesso!!!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
SandroSoftwares

tente:

double credito = Double.parseDouble(formatarValor(this.txtcredito.getText()));
double debito = Double.parseDouble(formatarValor(this.txtdebito.getText()));

Sandro

adsadilson

Sandro

ainda continuar com erro tem como vc verificar esse metodo formatarValor() se esta certo

Exception in thread AWT-EventQueue-0 java.lang.StackOverflowError

at java.lang.String.(String.java:234)

at java.lang.StringBuffer.toString(StringBuffer.java:561)

at java.text.DecimalFormat.expandAffix(DecimalFormat.java:2039)

at java.text.DecimalFormat.expandAffixes(DecimalFormat.java:1979)

at java.text.DecimalFormat.applyPattern(DecimalFormat.java:2664)

at java.text.DecimalFormat.(DecimalFormat.java:435)

at view.JDialogEdiLivroCaixa.formatarValor(JDialogEdiLivroCaixa.java:254)

at view.JDialogEdiLivroCaixa.formatarValor(JDialogEdiLivroCaixa.java:255)
SandroSoftwares

Tá certo sim.

a questão é que inserimos vírgula e ponto e pra salvar só podemos salvar o ponto dos centavos.

olha uma solução: (na verdade uma gambiarra... rsrsrs)

String a = formatarValor(this.txtcredito.getText()).replaceAll(".", "");//substitui o ponto por nada
String b = a.replaceAll(",", "."); //onde houver virgula (dos centavos) vire ponto

double credito = Double.parseDouble(b); //transformando a string b que agora  tem ponto em double

//fazendo a mesma coisa para debito:

a = formatarValor(this.txtdebito.getText()).replaceAll(".", "");//substitui o ponto por nada
b = a.replaceAll(",", "."); //onde houver virgula (dos centavos) vire ponto

double debito = Double.parseDouble(b); //transformando a string b que agora  tem ponto em double
adsadilson

Sandro conseguir resolver assim:

private double formatarValor(String valor) throws ParseException {
        DecimalFormat formatter = new DecimalFormat("##,##00.00");
        return new Double(formatter.parse(valor).toString());
    }

    private void salvarLancamento() {
        //Inserir os dados
        Date data = null;
        try {
            data = formatarData(this.txtdata.getText());
        } catch (ParseException ex) {
            System.out.println("erro ao formartar a data1" + ex);
        }
        String historico = this.txthistorico.getText();
        double credito = 0;
        double debito = 0;
        try {
            credito = formatarValor(this.txtcredito.getText());
            debito = formatarValor(this.txtdebito.getText());
        } catch (ParseException ex) {
            System.out.println("err na digitação dos valores:"+ex);
        }

eu ja tinha me metodo q formatava a data ai eu so mundei para formatar os valores. agora estou querendo inicar o jtextfiel com a data atual

adsadilson

Sandro eu lhe add no msn, se tive com vc me aceita para a gente troca ideia ou melhor passa mais algums probleminha rsrsr

SandroSoftwares

ok! meu email:

[email removido]

SandroSoftwares

tente fazer um teste digitando para o seu código o valor: 1.000,58

retorna o que como resposta?

SandroSoftwares

tá certo! eu que não tinha colocado o método aqui!
vai servir pra mim também!

SandroSoftwares

agora mesmo assim vc vai precisar filtrar o que o que o usuário digita.

sem a filtragem o código não está 100%

exemplo: se o usuário digitar 1.00 o sistema vai converter pra 100.0

tem algo doido aqui ainda… rsrsrs

adsadilson

como assim, fica online no msn
testei de todo maneira aqui é esta dando certo so q estou usando um JFormattexfiedl com as mascara para numero

SandroSoftwares

se digitar: 1,000.58 vai virar 1.0

Olha, eu costumo impedir esse tipo de coisa via expressão regular.

por exemplo: impeço o usuário de digitar certas coisas:

private boolean validaEntradaMonetaria(String recebeDadoDigitado) {
        Pattern padrao = Pattern.compile("[0-9,]*"); // 0-9 inumeras vezes
        Matcher pesquisa = padrao.matcher(recebeDadoDigitado);
        if (pesquisa.matches()) {

            return true;

        } else {
            JOptionPane.showMessageDialog(null, "Erro...Preencha valores monetários apenas com NÚMEROS e com a VÍRGULA dos centavos!\nRetire LETRAS, PONTO, ESPAÇO ou outros caracteres não permitidos no preenchimento!", "Erro...", JOptionPane.ERROR_MESSAGE);
            return false;

        }

    }

depois é só validar:

if (validaEntradaMonetaria(jTextFieldValorInicial.getText())) {
//se tiver certo faça!
}
adsadilson

entedi valeu

adsadilson

agora ficou bom de mais, muito obrigado Sandro se tive disposto a resolver problema é comigo mesmo viu tou cheio de bug aqui rsrsr

SandroSoftwares

Adilson, pesquisei aqui no fórum com o objetivo de diminuir a gambiarra que fizemos...

achei nesse link [url]http://www.guj.com.br/java/75279-duvidas-sobre-formatacao-do-tipo-moeda-no-jtextfield[/url]
essa classe:

muito boa, na verdade, maravilhosa! implementei aqui e deu tudo certo!

import javax.swing.text.*;

public class MonetarioDocument extends PlainDocument {

    public static final int NUMERO_DIGITOS_MAXIMO = 12;

    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {

        String texto = getText(0, getLength());
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (!Character.isDigit(c)) {
                return;
            }
        }

        if (texto.length() < this.NUMERO_DIGITOS_MAXIMO) {
            super.remove(0, getLength());
            texto = texto.replace(".", "").replace(",", "");
            StringBuffer s = new StringBuffer(texto + str);

            if (s.length() > 0 && s.charAt(0) == '0') {
                s.deleteCharAt(0);
            }

            if (s.length() < 3) {
                if (s.length() < 1) {
                    s.insert(0, "000");
                } else if (s.length() < 2) {
                    s.insert(0, "00");
                } else {
                    s.insert(0, "0");
                }
            }

            s.insert(s.length() - 2, ",");

            if (s.length() > 6) {
                s.insert(s.length() - 6, ".");
            }

            if (s.length() > 10) {
                s.insert(s.length() - 10, ".");
            }

            super.insertString(0, s.toString(), a);
        }
    }

    public void remove(int offset, int length) throws BadLocationException {
        super.remove(offset, length);
        String texto = getText(0, getLength());
        texto = texto.replace(",", "");
        texto = texto.replace(".", "");
        super.remove(0, getLength());
        insertString(0, texto, null);
    }
}

e para o textfield fazemos no construtor do frame:

jTextField1.setDocument(new MonetarioDocument());

Ele irá aceitar somente números. e caberá até 12 dígitos, ou seja, casa dos milhões (considerando pontos e vírgula inseridos automaticamente como em sites como bancos por exemplo!).

Para que a string retirada do getText do textfield (com pontos e vírgula) seja convertida em double só com o ponto dos centavaos ai sim, criei o método abaixo:

private double soDeixaPontoDosCentavos(String valor) throws ParseException {
        String resultado = "";
        String auxiliar = "";

        for (int anterior = 0, posterior = 1; jTextField1.getText().length() >= anterior; anterior++, posterior++) {
            if (posterior <= jTextField1.getText().length()) {
                if (valor.substring(anterior, posterior).equals(".")) {
                    //não faz nada
                } else {
                    auxiliar = auxiliar + valor.substring(anterior, posterior);
                    resultado = auxiliar;
                    System.out.println("ok " + resultado);
                }

            }
            //   System.out.println("anterior " + anterior);
            //System.out.println("posterior " + posterior+"\n\n");

        }
        System.out.println("final " + resultado);

        return new Double(resultado.replaceAll(",", "."));
    }

Tá muiiiiiiiiiiiiiiiiito melhor do que o outro!

SandroSoftwares

quando for usar o método:

double credito = 0; try { credito = soDeixaPontoDosCentavos(jTextField1.getText()); } catch (ParseException ex) { Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex); }

adsadilson

Sandro

Esse novo metodo q vc fez é especifico para um jTextfield né, caso exista mais campos monetario eu tenho q criar os metodos de novo né ou estou engando.
estou com mais um probleminha aqui tem uma tabela q lançar tando valores para credito como para debito, como eu faço para obter o saldo de cada registro lançando eu encontrei um sql q faz isso mais infelizmente tem alguns probleminhas quando é lançando registro retroativo. Vc tem um noção de como faço para obter o saldo dos registros.
Esse é o sql q estava usando apos salvar o registro

“update fluxocaixa set saldo=(select sum(credito)-sum(debito) from fluxocaixa as c where c.id <= fluxocaixa.id)”;

SandroSoftwares

é só chamar o método novamente pra outros campos monetários.

sendo que se houver outros campos textfields como monetários terá que fazer a mesma coisa no construtor:

jTextField2.setDocument(new MonetarioDocument());

você vai controlar isso via banco ou via aplicação? se for via aplicação creio que não necessita ter que gravar o saldo e sim somente os valores de credito e débito.
quando vc retornar esses valores ai sim vc subtrai e mostra pro usuário.

adsadilson

assim eu nao sei qual seria a melhor forma de controla esse evento se é no banco ou via programação. vc ja fez algo parecido.

SandroSoftwares

olha não desenvolvi nada pra comercio por exemplo, então não tenho ainda noção de como a galera faz controle de caixa.

Agora é possível sim fazer via aplicação.

Se por exemplo: Você quiser comprar 500,00 a vista em mercadoria vc faria uma consulta em créditos e débitos abatendo um do outro para ver se tem esse saldo disponível…

não sei até que ponto é vantajoso gravar saldo no banco de dados se vc dispõem de entrada e saída…

se alguém poder nos ajudar aqui, por favor!!!

adsadilson

Sandro, é o seguinte existe uma tabela fluxo de caixa onde cair nela os lançamento de credito e debito, o q eu quero é o seguinte ao vizualiar os dados dessa tabela no Jtable ele me mostra o saldo atual de cada registro, esse sql me traz o resultado desejado so com um probleminha.

select data, historico, credito, debito, (select sum(c.credito)-sum(c.debito) from caixa as c where c.id <= cx.id) as saldo from caixa cx
sé q ele esta trazendo assim

data historico credito debito saldo
01/01/2012 blabla 100,00 0,00 150,00
01/01/2012 blabla 50,00 0,00 150,00
02/01/2012 bablba 0,00 50,00 100,00

o certo seria assim

data historico credito debito saldo
01/01/2012 blabla 100,00 0,00 100,00
01/01/2012 blabla 50,00 0,00 150,00
02/01/2012 bablba 0,00 50,00 100,00

SandroSoftwares

eu faria esse controle via aplicação…

data ---------------- historico --------credito-----------debito--------saldo
01/01/2012--------- blabla-----------100,00------------0,00---------[color=red](saldo ant + crédito - débito)[/color] =100,00
01/01/2012--------- blabla------------50,00-------------0,00---------[color=red](saldo ant + crédito - débito)[/color] =150,00
02/01/2012--------- blabla--------------0,00-----------50,00---------[color=red](saldo ant + crédito - débito)[/color] =100,00

adsadilson

Sandro eu consegui resolver esse meu problema com uma funçao dentro do bando de dado postgres aqui esta o codigo mais como ficaria essa função via programação, ha essa tabela possui milhares de registros via programação nao fica lento a exibição dos dados.

CREATE OR REPLACE FUNCTION livrocaixa()
  RETURNS SETOF fluxocaixa AS
$BODY$
 declare
   r record;
   linha fluxocaixa;
   saldoatual double precision = 0;
 begin
   for r in
       
       select id, data, historico, credito, debito,saldo  from fluxocaixa 
     loop
       r.saldo = saldoatual + r.credito - r.debito;
       saldoatual = r.saldo;

   
       linha.data = r.data;
       linha.historico = r.historico;
       linha.credito = r.credito;
       linha.debito = r.debito;
       linha.saldo = r.saldo;
       return next linha;
     end loop;
            
  return;
 end
 $BODY$
  LANGUAGE 'plpgsql' VOLATILE

Eu preciso criar uma funçao via programação q receba paramet pq existe uma tabela de conta corrente onde tem q ser feito esse mesmo calculo

Nelsonjahn

Olá desculpe ativar esse tópico mas tenho uma dúvida que é a seguinte, se eu clikar em meu JTable, numa linha e fiz todo o processo de mostrar os dados no meus Jtesteis com esse código consigo vizualizar os valores nas caixas de texto depois de clikado na tabela, sim ou não? Obrigado pela atenção.

adsadilson

não entendi muito bem a sua duvida, ver se é isso q vc quer, ao selecionar uma linha da jtable mostrar os dados em outro componente é isso mesmo ou nao?

Nelsonjahn

Obrigado pela atenção, sim seria isso mesmo, eu atualmente tenho um formato de valor na minha caixa de texto
isso só na hora que eu digito ele me da certinho o valor, mas quando eu tenho salvo na tabela e eu clikar novamente nesse valor ou linha ele não mostra na caixa do valor porém todos os outros dados tipo texto ou munero normal mostra.
eu cliko ou seleciono uma linha que ele retorne os valores que estejam no jtable, tens algum exemplo, ou
isso não funciona através de um jtable, trabalho com Netbeans. um abraço.

adsadilson

O q vc quer dizer é quando digitar dentro da jtable ele não fica com o formato desejado é?
Vc esta usando um TableModel próprio ou ainda esta usando DefaultTableModel ?
Se estive usando um DefaultTableModel aconselho a criar o seu próprio TableModel segue o link de um exemplo:

Criado 8 de setembro de 2012
Ultima resposta 8 de nov. de 2012
Respostas 29
Participantes 4