Query para buscar por data(CURDATE, INTERVAL) [RESOLVIDO!]

Boa tarde pessoal, entao sou meio leigo em SQL, mas tenho que fazer uma query aqui…

Tenho uma entidade EVENTOS, que possui um campo data(date).

No caso preciso preciso pegar todos os eventos que estao com a data num intervalo de 7 dias.

Pesquisando fiz a seguinte query:

Não compila, da um erro de sintaxe =/;

Alguem pode me ajudar? =D

Boa tarde!!

Que banco esta utilizando? e qual o erro que te retorna?

Att.

opaa tardee

Então é o MySQL, ele retorna um erro de sintaxe após o ultimo parenteses…

Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘)’ at line 1

você deve fazer assim:

SELECT 
	* 
FROM 
	eventos 
WHERE 
	eventos.data > dateInitial
	AND evento.data <= dateFinish;

Mas de uma olhada em between também.

No sql acima você passa a data final e inicial e todos os eventos entre esse período são encontrados.

Até mais

Entendi, mas no caso teria que fazer algo que atualizasse conforme o dia atual entende… D=

Costumo usar essa expressão para retornar resultados em intervalo de datas:


    SELECT * from eventos where eventos.data between P_DATA_INICIAL and P_DATA_FINAL

Att.

Hmm blz… =D

Vcs sabem então como posso manipular essa Dt INICIAL e Dt FINAL?

Algo do tipo passar essa DT INICIAL como data atual(current_date) - 3 dias, e DT FINAL como data atual +4 dias?

Para setar o dia final após 7 dias você pode fazer o seguinte.

Calendar dataIni = Calendar.getInstance();
Calendar dataFim = Calendar.getInstance();

dataFim.setTime(dataIni);

dataFim.add(Calendar.DAY_OF_MONTH,7);

Daí na sua chamada você passa o date corresponte a data inicial e a final.

Para passar o date chame o método getTime de dataIni e dataFim

ManoJava o BETWEEN usa a seguinte expressão no postgressql

a >= x AND a <= y

portanto há casos que é preciso utilizar o AND, postei só para conhecimento mesmo, quem sabe ajude alguém.

Até mais.

obg pela resposta lele_vader

Mas sinceramente sou leigo e entendi pouco sobre sua resposta hahah

Se puder me ajudar com um pouco mais de detalhes… =D

Vou postar o que fiz

	public List<Evento> listar2() {
		try {
			
			List<Evento> eventos = new ArrayList<Evento>();
			
			Calendar dataIni = Calendar.getInstance(); 
			Calendar dataFim = Calendar.getInstance(); 
			
			dataFim.setTime(dataIni); 

			dataFim.add(Calendar.DAY_OF_MONTH,7); 

			
			PreparedStatement stmt = this.connection.prepareStatement("SELECT * from eventos where eventos.data between dataIni and dataFim");	
			
			
			ResultSet rs = stmt.executeQuery();
			
				while (rs.next()) {
					eventos.add(populaEvento(rs));
				}
				
			rs.close();
			stmt.close();
			
			return eventos;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		
	}

como eu passo esse dataIni e dataFim na string SQL?

Nao entendi esse metodo get time…

PreparedStatement tem um método que você seta os parâmetros.


    public List<Evento> listar2() {  
        try {  
              
            List<Evento> eventos = new ArrayList<Evento>();  
              
            Calendar dataIni = Calendar.getInstance();   
            Calendar dataFim = Calendar.getInstance();   
              
            dataFim.setTime(dataIni);   
      
            dataFim.add(Calendar.DAY_OF_MONTH,7);   
      
              
            PreparedStatement stmt = this.connection.prepareStatement("SELECT * from eventos where eventos.data between ? and ?");    
              
           stmt.setDate(1,dataIni);
           stmt.setDate(2,dataFim);

            ResultSet rs = stmt.executeQuery();  
              
                while (rs.next()) {  
                    eventos.add(populaEvento(rs));  
                }  
                  
            rs.close();  
            stmt.close();  
              
            return eventos;  
        } catch (SQLException e) {  
            throw new RuntimeException(e);  
        }  
          
    }  

O get Time é porque o método stmt.setDate espera um objeto Date e você criou a data usando o objeto Calendar, daí getTime retorna um objeto Date a partir desse Calendar.

A sua consulta tem que passar ? para os parâmetros que são dinâmicos.

Daí o stmt.getDate com parâmetro 1 e 2, correspondendo as 2 ?

Lembrando que você precisa pegar a data inicial e chamar o dataIni.setTime e passar a data inicial.

Como você pega ela ?

Entendi sobre ?, para passar parametros dinamicos

Entendi agora tbem sobre o getTime, ele realmente espera um objeto date… mas onde declaro isso, seria algo assim:

A data inicial seria a (data atual - 3 dias), o ideal seria criar outra query para passar esse valor como parametro?

getTime é um método de um objeto Calendar sacou ?

dataFim.setTime(dataIni);

Não sabia como seria antes a dataIni, então por isso coloquei achando que seria já pronto.Sendo assim coloca assim.

Calendar.getInstance já traz um objeto com a data de hoje.

Calendar dataHoje = Calendar.getInstance();
Calendar dataIni = Calendar.getInstance();

dataIni.setTime(dataHoje.add(Calendar.DAY_OF_MONTH,-3));

Coloca isso antes de mexer com a dataIni e a query.

Eu sei que é estranho, mas você chama o método add passando um número negativo para diminuir o tempo.

É por essas e outras que mexer com data em java é brabo.

okay! coloquei o data Hoje e o set time (é estranho mesmo, mas até que faz sentido)

Ta assim:

	public List<Evento> listar2() {
		try {
			
			List<Evento> eventos = new ArrayList<Evento>();
			
			Calendar dataHoje = Calendar.getInstance(); 
			Calendar dataIni = Calendar.getInstance(); 
			Calendar dataFim = Calendar.getInstance(); 

			
			dataIni.setTime(dataHoje.add(Calendar.DAY_OF_MONTH,-3)); 
			
			dataFim.setTime(dataIni);
			
			dataFim.add(Calendar.DAY_OF_MONTH,7); 
			
			PreparedStatement stmt = this.connection.prepareStatement("SELECT * from eventos where eventos.data between ? and ?");	
			
			stmt.setDate(1,dataIni);  
		    stmt.setDate(2,dataFim); 
			
			ResultSet rs = stmt.executeQuery();
			
				while (rs.next()) {
					eventos.add(populaEvento(rs));
				}
				
			rs.close();
			stmt.close();
			
			return eventos;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		
	}

o getTime é um metodo do objeto calendar, percebi agora… mas ainda não entendi como declarar isso =X

Não declara.
Você chama

Por sinal esqueci de colocar aqui também.
dataIni.setTime(dataHoje.add(Calendar.DAY_OF_MONTH,-3).getTime());

stmt.setDate(1,dataIni.getTime());
stmt.setDate(2,dataFim.getTime());

Veja a descrição do método na documentação.

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html

Olhe o método getTime

Sim, chamar, erro meu estava usando o termo errado!

Entendi agora onde colocar porem ainda persiste alguns erros… =/


	public List<Evento> listar2() {
		try {
			
			List<Evento> eventos = new ArrayList<Evento>();
			
			Calendar dataHoje = Calendar.getInstance(); 
			Calendar dataIni = Calendar.getInstance(); 
			Calendar dataFim = Calendar.getInstance(); 

			
			dataIni.setTime(dataHoje.add(Calendar.DAY_OF_MONTH,-3).getTime()); 
			
			dataFim.setTime(dataIni.getTime());
			
			dataFim.add(Calendar.DAY_OF_MONTH,7); 
			
			PreparedStatement stmt = this.connection.prepareStatement("SELECT * from eventos where eventos.data between ? and ?");	
			
			stmt.setDate(1,dataIni.getTime());  
		    stmt.setDate(2,dataFim.getTime()); 
			
			ResultSet rs = stmt.executeQuery();
			
				while (rs.next()) {
					eventos.add(populaEvento(rs));
				}
				
			rs.close();
			stmt.close();
			
			return eventos;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		
	}

Nessas linhas:

stmt.setDate(1,dataIni.getTime());  
 stmt.setDate(2,dataFim.getTime()); 

Erro: The method setDate(int, Date) in the type PreparedStatement is not applicable for the arguments (int, Date)

e também: =/

dataIni.setTime(dataHoje.add(Calendar.DAY_OF_MONTH,-3).getTime());

Erro: Cannot invoke getTime() on the primitive type void

CAra vc ta me ajudando muito, nunca que iria fazer tudo isso sozinho

Tenho que ir pra facul agora, mas amanha volto e posto aqui, por favor nao suma haha =DD

O 2 erro foi culpa minha mesmo.

Quis fazer tudo em uma linha e não é assim.

Tenta assim:

dataHoje.add(Calendar.DAY_OF_MONTH,-3);
dataIni.setTime(dataHoje.getTime());

O 1 é mais sutil.
A porcaria do preparedStatement usa o parâmetro Date da classe java.sql.Date, porém o objeto que você passou para ele é do pacote java.util.Date

Para corrigir faça isso aqui para cada stmt.setDate()

stmt.setDate(1,new java.sql.Date(dataIni.getTimeInMillis() );

Aí foi usado o método para getTimeInMillis, pois o construtor da classe java.sql.Date espera um long e não um java.util.Date. Daí esse método te retorna o Date em long sacou.

http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/Date.html

Falta também na sua classe adicionar um finally para fechar os recursos.

No caso o fechamento do PreparedStament e o ResultSet
devem estar em um finally, pois se a aplicação der um erro ficarão recursos presos.

Também coloque a declaração do PreparedStatement  e no ResultSet antes do try, senão não terão visibilidade no finally.

No início do método adicione isso.
PreparedStatement stmt = null;
ResultSet rs;

Ao final do catch adicione isso.
finally{
 if(rs !=null){
    try{
      rs.close();
   }catch(SQLException exc1){
     throw new RuntimeException(exc1);  
   }
  }
  if(stmt!=null){
   try{
     stmt.close(); 
  }catch(SQLException exc2){
      throw new RuntimeException(exc2);  
   }
 }
}

Por fim não coloque throw new RuntimeException(e);
É mais elegante você criar uma exceção sua e daí extenalizar para outras camadas.

algo como:

throw new ErroBancoException(e);

Funcionou!! =DDD

Vlw mesmo lele_vader, muito obrigado pela paciencia para ajudar!

O código final ficou assim:


public List<Evento> listar2() {
		
		PreparedStatement stmt = null;
		ResultSet rs = null;
		
		
		try {
			
			List<Evento> eventos = new ArrayList<Evento>();

			
			Calendar dataHoje = Calendar.getInstance(); 
			Calendar dataIni = Calendar.getInstance(); 
			Calendar dataFim = Calendar.getInstance(); 

			dataHoje.add(Calendar.DAY_OF_MONTH, -3);
			
			dataIni.setTime(dataHoje.getTime());
			
			dataFim.setTime(dataIni.getTime());
			
			dataFim.add(Calendar.DAY_OF_MONTH,7); 
			
			stmt = this.connection.prepareStatement("SELECT * from eventos where eventos.data between ? and ?");	
			
			stmt.setDate(1, new java.sql.Date(dataIni.getTimeInMillis()));  
		    stmt.setDate(2, new java.sql.Date(dataFim.getTimeInMillis())); 
			
			rs = stmt.executeQuery();
			
				while (rs.next()) {
					eventos.add(populaEvento(rs));
				}
				
			rs.close();
			stmt.close();
			
			return eventos;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		
		
		finally{
			
			if(rs !=null){ 
			    try{  
			    	rs.close();  
			   }catch(SQLException exc1){  
				   throw new RuntimeException(exc1);    
			   }
			  } 
			
			if(stmt!=null){  
			   try{  
				   stmt.close();   
			  }catch(SQLException exc2){  
			      throw new RuntimeException(exc2);    
			   }  
			 }
		}
	}
	

Vou ver depois a parte das excessões, mas vlw msm!

Tire o rs.close() e o stmt.close() do try/catch

Coloque o return eventos e a instanciação do List
para fora do try/catch