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

21 respostas
E

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

21 Respostas

ManoJava

Boa tarde!!

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

Att.

E

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

Danilo_Carvalho

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

E

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

ManoJava

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.

E

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?

lele_vader

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

Danilo_Carvalho

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.

E

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…

lele_vader

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 ?

E

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?

lele_vader

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.

E

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

lele_vader

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

E

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

lele_vader

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

lele_vader

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);

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!

lele_vader

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

E

Opa código com as correções:

public List<Evento> listar2() {
		
		PreparedStatement stmt = null;
		ResultSet rs = null;
		List<Evento> eventos = new ArrayList<Evento>();
		
		try {
		
			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 ? ORDER BY data, horario");	
			
			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));
				}
			
			
		} 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);    
			   }  
			 }
		}
		
		return eventos;
	}
lele_vader

Isso.
Vê se funciona e tenta principalmente entender o código.
Qualquer coisa coloca um novo tópico aí ou me manda uma mp.

Vlw.

Criado 12 de setembro de 2012
Ultima resposta 13 de set. de 2012
Respostas 21
Participantes 4