[RESOLVIDO] Problema com data prepareStatement em banco Oracle

Prezados,
Estou fazendo um select em um banco de dados Oracle, onde eu buco os dados de acordo com um periodo de datas.

Porem, o erro retornado esta abaixo:
java.sql.SQLException: ORA-00932: inconsistent datatypes: expected DATE got NUMBER

Abaixo segue uma parte do código:

 String dataini = "01/05/2018";
    String datafim = "28/05/2018";
    Connection con = null;
    Conexao c = null;
  
    try {
        c = new Conexao();
        con = c.criaConexao();
        PreparedStatement ps = con.prepareStatement("SELECT VEN.APELIDO,\n" +

" SUM(CAB.VLRNOTA) AS TOTAL\n" +
" FROM TGFCAB CAB, TGFTPV TPV, TGFTOP TOP, TGFVEN VEN\n" +
" WHERE\n" +
" CAB.CODVEND = VEN.CODVEND \n" +
" AND CAB.CODTIPVENDA = TPV.CODTIPVENDA\n" +
" AND CAB.CODTIPOPER = TOP.CODTIPOPER\n" +
" AND CAB.DHTIPOPER = TOP.DHALTER\n" +
" AND CAB.DHTIPVENDA = TPV.DHALTER\n" +
" AND CAB.CODTIPOPER IN (3902,3914,3200,3214,3919,3207,3913) – Informe aqui suas TOPs\n" +
" AND TRUNC(CAB.DTNEG) >= " + dataini + “\n” +
" AND TRUNC(CAB.DTNEG) <= " + datafim + " \n" +
" AND CAB.STATUSNOTA = ‘L’\n" +
" GROUP BY VEN.APELIDO\n" +
" ORDER BY TOTAL");

Alguem sabe como que eu posso trabalhar com datas neste caso?

Lembrando que essa query roda perfeitamente dentro do oracle.

Usar o PreparedStatement como Statement não ajuda. Faça o uso correto do que você precisa.

PreparedStatement ps = con.prepareStatement("SELECT VEN.APELIDO,\n" +
" SUM(CAB.VLRNOTA) AS TOTAL\n" +
" FROM TGFCAB CAB, TGFTPV TPV, TGFTOP TOP, TGFVEN VEN\n" +
" WHERE\n" +
" CAB.CODVEND = VEN.CODVEND \n" +
" AND CAB.CODTIPVENDA = TPV.CODTIPVENDA\n" +
" AND CAB.CODTIPOPER = TOP.CODTIPOPER\n" +
" AND CAB.DHTIPOPER = TOP.DHALTER\n" +
" AND CAB.DHTIPVENDA = TPV.DHALTER\n" +
" AND CAB.CODTIPOPER IN (?) – Informe aqui suas TOPs\n" +
" AND TRUNC(CAB.DTNEG) >= ? \n” +
" AND TRUNC(CAB.DTNEG) <= ? \n" +
" AND CAB.STATUSNOTA = ?\n" +
" GROUP BY VEN.APELIDO\n" +
" ORDER BY TOTAL");

ps.setString(1, "3902,3914,3200,3214,3919,3207,3913");
ps.setDate(2, new java.sql.Date(converteStringParaData("01/05/2018").getTime());
ps.setDate(3, new java.sql.Date(converteStringParaData("28/05/2018").getTime());
ps.setString(4, "L");

ps.execute();
ResultSet rs = ps.getResultSet();

Detalhe, o método converteStringParaData você precisa criar. Ao menos isso, né, fera?

Criei o metodo para converter String em Date, porem não esta retornando o que eu preciso ainda que seria a data no formato dd/MM/YYYY.
Ainda nao consegui achar o motivo.

 public Date converteStringParaData (String dt){
    SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
    Date datainfo = null;
    try {
        datainfo = (Date)formatter.parse(dt);
    } catch (ParseException ex) {
        Logger.getLogger(Banco.class.getName()).log(Level.SEVERE, null, ex);
    }
    return datainfo;
}

Cara, pare de bobagem.
Se você setar através do método setDate, não tem formato, entendeu?
A não ser que a coluna tenha sido criada como varchar, aí é uma coisa (ridícula) totalmente diferente.

Cara olha só…
Bobagem é um coisa e duvida é outra coisa, mas vamos la…
Se nao tem formato eu nao entendi o motivo de utilizar um metodo converteStringParaData, como vc descreveu anteriormente.
Resumindo eu só quero fazer um select no banco. Sempre fiz com outros bancos só com o Oracle que estou tendo essa dificuldade.

A razão é que você SÓ PODE CRIAR UM OBJETO DA CLASSE java.sql.Date a partir de um double que corresponde aos milissegundos de uma DATE.
Se você encontrar um meio de transformar uma String em um java.sql.Date, boa sorte, mas eu desconheço.

Darlan, desculpe a minha ignorancia.
Mas o que eu tenho que fazer entao para funcionar o metodo converteStringParaData ?

Eu preciso fazer funcionar a linha abaixo para que meu SELECT possa rodar.
ps.setDate(2, new java.sql.Date(converteStringParaData("01/05/2018").getTime()));

Cara, você precisa, antes de qualquer coisa, estudar, né, meu caro?

O problema original era a exceção que dizia ter encontrado número quando esperava date, não era isso? Este problema foi corrigido?

Meu querido, é o seguinte.
Não estou aqui para ouvir a sua opiniao sobre se eu tenho que estudar ou não. Desde a sua primeira mensagem vc esta sendo arrogante. Vc nem me conhece para falar assim comigo. Se vc nao quer ajudar leia o topico e vai ver outra coisa, mania idiota de querer TENTAR rebaixar as pessoas que precisam de um auxilio, que querem tirar uma duvida ou outra, parece até que vc nasceu sabendo programar JAVA e nunca precisou tirou alguma duvida, não é?
Triste ter pessoas assim, como vc num site referencia justamente para expansão do conhecimento.

Muito obrigado pela sua ajuda.
Fica em paz!

1 curtida

Arrogante?
Cara, eu respondi a pergunta, mostrei um caminho. Agora, se ser alguém “não arrogante” é dar a resposta pronta e você só copiar e colar no seu trabalhinho de faculdade, então, realmente, eu sou muito arrogante.
Eu, sinceramente, não tenho a mínima culpa se você está sendo incrivelmente teimoso em não aceitar as minhas sugestões. Não tenho o que fazer quanto a isso.

E, sim, você precisa estudar. Isso é um requisito básico para toda e qualquer pessoa quer almeja ser programador (na verdade, qualquer pessoa que quer ser alguma coisa nessa vida).

1 curtida

Falou bonito!

E ainda vc diz nao ser arrogante né Darlan? Conselho, respire e pense antes de falar…vai ter fazer bem, ja fui assim um dia e só quebrei a cara…
Serio, tenho pena de pessoas assim de verdade. Se vc ler as minhas respostas, vc vai ver que aceitei todas as respostas que vc deu, inclusive alterei meu codigo inicial (nao copiado e nao faz parte de um trabalhinho), inserindo a sugestao proposta por vc. Inumeras vezes eu perguntei pq eu nao estava entendendo.
Só pelo fato de eu gostar da linguagem nao significa que eu preciso estar no mesmo nivel que vc, entendeu, é isso que queria que vc entendesse. Existem diversas formas de vc dar um resposta para uma pessoa. Serio, vc pode “matar” profissionalmente um jovem por exemplo que esta começando agora respondendo assim.
É só meu ponto de vista, achei desnecessario esse nivel de “arrogancia” nas respostas…

Fera, eu tenho pena de gente com preguiça de pensar, estudar e trabalhar. De resto, cada um faz seu espaço.

Você tem duas formas de fazer essa consulta extremamente básica.
Ou segue o que eu sugeri ou você faz do jeito feio e errado, que é utilizando a conversão direta pelas funções do Oracle

SELECT
FROM
WHERE COLUNA_DATA BETWEEN TO_DATE('10/10/2010', 'DD/MM/YYYY") AND TO_DATE('10/11/2010', 'DD/MM/YYYY");

Mas, aí é você que define o que acha menos pior.

Darlan, pelo modo que vc sugeriu eu tenho duvida em relação ao metodo que preciso criar.
Como vc viu mesmo que errado eu cheguei criar o metodo para converter a String em Data, mas mesmo assim não rolou. Por qual caminho preciso ir?

Vamos lá, a formatação de datas é uma abstração necessária para atender as necessidades de determinadas situações, como apresentação da data e hora a usuários, como registro em sistemas, relatórios ou passagem das mesmas para outros sistemas via web services, por exemplo.
Quando falamos em data, no java, especificamente a classe java.util.Date, você tem é uma representação, em milissegundos, da data 00:00:00 01/01/1970 até o momento em que o objeto da mesma é criado.
Por isso você precisa do DateFormat (ou SimpleDateFormat).

Especificamente no método criado, você espera uma data no padrão brasileiro (dd/MM/yyyy) e devolve uma instância de objeto da classe Date (java.util). Ou seja, você está dizendo ao java que quer uma instância de objeto que corresponda ao dia, mês e ano que está definido nesta String, então o JRE que se vire para descobrir quantos milissegundos se passaram da data de início para a data especificada.

Em relação a consultas SQL, você tem 3 opções:

Date - java.sql.Date - Refere-se a datas e o formato da mesma é yyyy-MM-dd
Timestamp - java.sql.Timestamp - Refere-se a hora e data, formato hh:mm:ss yyyy-MM-dd
Time - java.sql.Time - Refere-se à hora, formato hh:mm:ss

Então, quando orientei que fizesse a alteração para aquele formato de query e passagem de parâmetro como sendo uma instância de java.sql.Date, era para isso.
Esta classe possui um construtor sobrecarregado e uma das sobrecargas recebe um long representando a data (o que é possível obter a partir do método getTime da classe java.util.Date).

Mais informações sobre java.sql.Date, aqui

Então, o formato sugerido deveria permitir que a consulta fosse efetuada sem problemas.

Com relação ao segundo modo, você pode passar a String que representa a data, no formato que já utilizava, sem maiores problemas, como parâmetro

WHERE COLUNA_DATA BETWEEN TO_DATE(?, 'DD/MM/YYYY') // onde ? é o X

stm.setString(x, "10/10/2010")

Entao, fazendo desta forma o retorno que eu tenho é:
java.sql.SQLException: ORA-01722: invalid number

Mas é porque no banco o campo é do tipo Date e prepareStatement estou setando ele como String. Ufa! Dai começa tudo aquilo de novo relacionado a conversao, entendeu?

E do outro jeito?

Da outra forma também esta retornando invalid number.

Olha só como esta meu metodo.

  public Date converteStringParaData (String dt){
    DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
    Date data = null;
    try {
    Date parsed = formatter.parse(dt);
    data = new java.sql.Date(parsed.getTime());
    } catch (ParseException ex) {
        Logger.getLogger(Banco.class.getName()).log(Level.SEVERE, null, ex);
    }
    return data;
}

Cara, o problema não está neste método. Ele retorna a data, você seta a data e faz a busca pela data.
Aliás, só agora fui me atentar:

E

São duas exceções distintas e diferentes.

Precisa analisar exatamente quais são as mensagens de erro retornadas, para ter um ponto específico para analisar.

Esse TRUNC(CAB.DTNEG) e TRUNC(CAB.DTNEG) não vão trazer o dia mais próximo, nesse caso um número inteiro?
Aí realmente tem que dar problema se você compara um objeto Date com um número…