Converter Date para Banco SQLServer (dd/MM/yyy para yyyy-mm-dd) [RESOLVIDO]

4 respostas
Alvaro_Junqueira

Boa noite pessoal,

estou com o seguinte problema:

tenho dois tipos diferentes de campo no meu JFrame, um é JTextField e o outro é um JDateChooser (componente do JCalendar)

quando trago do Banco

private Date DataNasc; this.DataNasc = rs.getDate("DataNasc");

tenho um Date
consigo colocar no JDataChooser legalzinho
e no JTextField, coloco assim pra ficar bonitinho:

public static String converterParaTela(Date date){ String formatada; try { SimpleDateFormat formatar = new SimpleDateFormat("dd/MM/yyyy"); formatada = formatar.format(date); } catch (Exception ex) { throw ex; } return formatada; }

o problema é ao jogar no banco, porque precisa ser no formato: yyyy-MM-dd
para o UPDATE ou INSERT aceitar!!

tentei fazer um gato aqui:

public static Date converterParaBanco(Date date){ String dateParaString; Date stringParaDate = new Date(); SimpleDateFormat formatar = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat formatar2 = new SimpleDateFormat("dd/MM/yyyy"); try { dateParaString = formatar2.format(date); stringParaDate = formatar.parse(dateParaString); } catch (Exception ex) { ex.printStackTrace(); } return stringParaDate; }

claro que dá erro né…rs

esse método acima dá o erro:

java.text.ParseException: Unparseable date: "28/06/1989"

e o erro ao gravar dá o erro no SQLException

241 - Falha ao converter data e/ou hora da cadeia de caracteres.

já tentei de várias maneiras, hora consigo uma data do tipo: Wen Jun 28 BR…
ou as vezes um long bem estranho…tipo [telefone removido] ( :cry: )

alguem conhece algum método legal para jogar no banco?

dessas maneiras que citei que trago, fooi de alguns códigos que achei pesquisando!
o que eu faço de errado?

agradeço a ajuda!!

4 Respostas

A

Alvaro Junqueira, que objeto está usando para interagir com o banco?
Se for um PreparedStatement, não precisa se preocupar com conversões, ele possui o setDate que faz isto para você.
Se não for um PreparedStatement, use um PreparedStatement.

Quando trabalhar com datas, você pode pensar nela como um valor…sem formato associado.
Data com formato é String, em algum momento você terá de dar Parse para transformar em Date novamente.

A maioria dos bancos de dados possui um formato de data padrão.
Passando uma String neste formato ele fará automaticamente o parse para Date (ou Datetime).
O problema dessa abordagem é que esse formato padrão pode ser alterado.
Daí um dia sua aplicação pára de funcionar “do nada” pois este formato foi altearado.

Em resumo, sempre garanta o formato de entrada e saída, não confie no formato padrão do banco.

E trabalhe sempre com o tipo de dados certo: Número, Texto ou Data.

Alvaro_Junqueira

oi AbelBueno, obrigado pela resposta

estou usando o:

conn = DriverManager.getConnection(Base.conectionString()); stm = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

apenas troco o createStatement para preparedStatement?
vou testar…

eu havia pensado dessa maneira errada até, trocando tudo para String e pau no gato…
concordo que deve ser usado Int, Date, etc…

A

Quase isso… com o stm você deve montar sua query com algo assim:

String sql = "SELECT * FROM TABELA WHERE CAMPO_VARCHAR_1 = '" + param1 + "' AND CAMPO_DATA_2 = '" + formatter.format(param2,formato) + "'";

Repare que o código acima, tem o problema de ser vulnerável a Sql Injection

Com o prepared você teria o código assim:

String sql = "SELECT * FROM TABELA WHERE CAMPO_VARCHAR_1 = ? AND CAMPO_DATA_2 = ?";
preparedStatement.setString(1,param1);
preparedStatement.setDate(2, param2 );

Você não precisa mais se preocupar com o tipo do campo na query…nem precisa das aspas simples…
E de quebra, você ainda deixa seu código protegido contra os ataques da Sql Injection.

ps: pra ser honesto, terá que converter um java.util.Date para um java.sql.Date…mas isso é mole…

Infelizmente isso é muito comum por aí… a velha Programação Orientada a Strings…

Com String tudo parece mais fácil: aceita em qualquer lugar, converte pra qualquer coisa…
Mas com o tempo fica muito fácil ter um monte de informação inválida circulando pelo sistema.

Alvaro_Junqueira

Funcionou!! uhulll!
Rapaz, entendi agora como faz, vou postar aqui como ficou, caso alguem tenha a mesma duvida

primeiro, comecei a usar o PreparedStatement:

PreparedStatement pstmt =  Base.conn.prepareStatement //Base é a minha classe de conexão com o banco, a connection  !
            (                 
               "UPDATE tblCliente "
              + " SET [Nome] = ? "
              + " ,[Pesquisa] = ? "
              + " ,[DataDoCadastro] = ? "
              + " ,[Telefone] = ? "
              + " ,[Sexo] = ? "
              + " ,[DataNasc] = ? "
              + " ,[Logradouro] = ? "
              + " ,[Bairro] = ? "
              + " ,[Numero] = ? "
              + " ,[Cep] = ? "
              + " ,[Complemento] = ? "
              + " ,[Observacao] = ? "
              + " ,[Cidade] = ? "
              + " ,[Estado] = ? "
              + " ,[ClienteEPaciente] = ? "
              + " WHERE ClienteID = ? "
            );
            pstmt.setString(1, this.Nome);
            pstmt.setString(2, this.Pesquisa);
            pstmt.setDate(3, this.DataDoCadastro);
            pstmt.setString(4, this.Telefone);
            pstmt.setString(5, this.Sexo);
            pstmt.setDate(6, this.DataNasc);
            pstmt.setString(7,this.Logradouro);
            pstmt.setString(8, this.Bairro);
            pstmt.setString(9, this.Numero);
            pstmt.setString(10, this.Cep);
            pstmt.setString(11, this.Complemento);
            pstmt.setString(12, this.Observacao);
            pstmt.setString(13, this.Cidade);
            pstmt.setString(14, this.Estado);
            pstmt.setInt(15, Funcionalidade.ConverterBooleanEmInt(this.ClienteEPaciente));
            pstmt.setInt(16, this.ClienteID);
            
            pstmt.executeUpdate();

depois, na minha tela, arrumei os campos:

JTextField
objCliente.setDataDoCadastro(ManipularData.converterParaBanco(txtDataDoCadastro.getText()));
e JDataChooser
objCliente.setDataNasc(new java.sql.Date(txtDataDeNascimento.getDate().getTime()));

como eu tinha que converte-los para sql.Date, no JDataChooser foi moleza, já que ele retorna util.Date
mas no JTextField, fiz um método na minha classe "ManipularData" chamado "converterParaBanco"

que está assim:

public static java.sql.Date converterParaBanco(String date){
        Date stringParaDate =  new Date();
        SimpleDateFormat formatar = new SimpleDateFormat("dd/MM/yyyy");
            try
            {
                stringParaDate = formatar.parse(date);  
            }
            catch (Exception ex) 
            {
                ex.printStackTrace();
            }
        java.sql.Date dataSql = new java.sql.Date(stringParaDate.getTime());
        return dataSql;
    }

e é isso...depois de feito parece moleza né...hsuahsuahsua
mas não foi não, apanhei hein!!

brigadão AbelBueno!!
:D

ainda de quebra aprendi sobre SQL Injection, e acabei implementando um nivel de segurança =]

Criado 19 de setembro de 2011
Ultima resposta 20 de set. de 2011
Respostas 4
Participantes 2