none
Filtrar datas RRS feed

  • Pergunta

  • Bom dia,

    pessoal.

     

    Eu já vi essa pergunta aqui no fórum, mas não encontrei pela pesquisa!

    No caso, eu fiz uma procedure para filtrar dados de uma tabela historico pela data, ficando:

     

    Code Snippet

    SELECT CodHistorico, DataHistorico

    FROM TB_Historico

    WHERE CodAparelho = @CodAparelho

    AND DataHistorico

    BETWEEN @DataInicio AND @DataFim

    ORDER BY DataHistorico DESC;

     

     

    Executando o código pelo MSSQL 2005 está funcionando, mesmo quando passo para as variáveis datas iguais, como:

    @CodAparelho = 5

    @DataInicio = 27/01/2009

    @DataFim = 27/01/2009

     

    Com isso, ele me traz apenas histórico do dia 27.

    Mas pelo aplicativo em C#, não está trazendo quando é no mesmo dia ou, quando tem um histórico pela data de inicio, só traz o histórico da data seguinte ao do inicio.

    Alguém saberia me dizer o motivo e como solucionar?

    Eu lembro que tinha algo haver com o horário, mas não lembro como resolver!

    Para passar as datas pela procedure estou utilizando variáveis do tipo DateTime.

    quarta-feira, 28 de janeiro de 2009 11:23

Respostas

  • Bom Dia Marcelo,

     

    O primeiro passo é "abolir" o formato dd/mm/yyyy e utilizar apenas o formato yyyymmdd nas comparações de datas, pois, ele não é sensível a qualquer tipo de configuração que venha a alterar o resultado da consulta. Para não ter problemas com horário sugiro o seguinte:

     

    Code Snippet

    SELECT CodHistorico, DataHistorico

    FROM TB_Historico

    WHERE CodAparelho = @CodAparelho

    AND (DataHistorico >= @DataInicio DataHistorico < DATEADD(D,1,@DataFim)

    ORDER BY DataHistorico DESC;

     

    Dessa forma, se você passar o dia 27, o filtro ficará entre todas as datas do dia 27 (00:00 inclusive) e dia 28 (00:00 exclusive). Esse tipo de construção também é bem mais performático que utilizar funções como o MONTH ou o CONVERT.

     

    [ ]s,

     

    Gustavo Maia Aguiar

    http://gustavomaiaaguiar.spaces.live.com

     

    quarta-feira, 28 de janeiro de 2009 11:37
  • Olá Gustavo.

     

    Mas não seria melhor fazer um select com BETWEEN?

    Sobre a sua sugestão, não há necessidade de converter a data que está no formato dd/MM/yyyy? O select irá funcionar seja qual for o formato que estiver configurado, correto?

     

     

    Bem, eu fiz uma pequena alteração no código e desta vez funcionou com o BETWEEN. Estou agora formatando a data sempre para yyyyMMdd, como você tinha me falado e com isso resolveu o problema:

    Code Snippet

    scmHistorico.Parameters.AddWithValue("@DataInicio", dataInicio.ToString("yyyy/MM/dd"));

    scmHistorico.Parameters.AddWithValue("@DataFim", dataFim.ToString("yyyy/MM/dd"));

     

     

     

    Antes eu estava enviando para a procedure com o formato padrão do meu SO, que era dd/MM/yyyy!

    Code Snippet

    scmHistorico.Parameters.AddWithValue("@DataInicio", dataInicio);

    scmHistorico.Parameters.AddWithValue("@DataFim", dataFim);

     

     

    quarta-feira, 28 de janeiro de 2009 13:08

Todas as Respostas

  • Bom Dia Marcelo,

     

    O primeiro passo é "abolir" o formato dd/mm/yyyy e utilizar apenas o formato yyyymmdd nas comparações de datas, pois, ele não é sensível a qualquer tipo de configuração que venha a alterar o resultado da consulta. Para não ter problemas com horário sugiro o seguinte:

     

    Code Snippet

    SELECT CodHistorico, DataHistorico

    FROM TB_Historico

    WHERE CodAparelho = @CodAparelho

    AND (DataHistorico >= @DataInicio DataHistorico < DATEADD(D,1,@DataFim)

    ORDER BY DataHistorico DESC;

     

    Dessa forma, se você passar o dia 27, o filtro ficará entre todas as datas do dia 27 (00:00 inclusive) e dia 28 (00:00 exclusive). Esse tipo de construção também é bem mais performático que utilizar funções como o MONTH ou o CONVERT.

     

    [ ]s,

     

    Gustavo Maia Aguiar

    http://gustavomaiaaguiar.spaces.live.com

     

    quarta-feira, 28 de janeiro de 2009 11:37
  • Olá Gustavo.

     

    Mas não seria melhor fazer um select com BETWEEN?

    Sobre a sua sugestão, não há necessidade de converter a data que está no formato dd/MM/yyyy? O select irá funcionar seja qual for o formato que estiver configurado, correto?

     

     

    Bem, eu fiz uma pequena alteração no código e desta vez funcionou com o BETWEEN. Estou agora formatando a data sempre para yyyyMMdd, como você tinha me falado e com isso resolveu o problema:

    Code Snippet

    scmHistorico.Parameters.AddWithValue("@DataInicio", dataInicio.ToString("yyyy/MM/dd"));

    scmHistorico.Parameters.AddWithValue("@DataFim", dataFim.ToString("yyyy/MM/dd"));

     

     

     

    Antes eu estava enviando para a procedure com o formato padrão do meu SO, que era dd/MM/yyyy!

    Code Snippet

    scmHistorico.Parameters.AddWithValue("@DataInicio", dataInicio);

    scmHistorico.Parameters.AddWithValue("@DataFim", dataFim);

     

     

    quarta-feira, 28 de janeiro de 2009 13:08
  • Olá Marcelo,

     

    Nesse caso o BETWEEN pode atrapalhar. Como ele considera os dois valores, no meu exemplo ele irá retornar registros do dia 28 (00:00) e isso não é desejável. Se o parâmetro adicionado já for do tipo DateTime ou SmallDateTime, não há necessidade de realizar nenhuma conversão.

     

    [ ]s,

     

    Gustavo Maia Aguiar

    http://gustavomaiaaguiar.spaces.live.com

     

    quarta-feira, 28 de janeiro de 2009 13:31
  • Ok, no caso é do tipo DateTime, tanto as variáveis que utilizo no C# quanto os campos do SQL SERVER também.

    Mas da forma que eu fiz, formatando a data para yyyymmdd, acredito que posso deixar também, correto?

    Já que está funcionando corretamente.

     

    quarta-feira, 28 de janeiro de 2009 13:44
  • Olá Marcelo,

     

    Pode manter como está. Não vai lhe trazer problemas entre o Regional Settings de sua aplicação e o Default Language do usuário

     

    [ ]s,

     

    Gustavo Maia Aguiar

    http://gustavomaiaaguiar.spaces.live.com

    quarta-feira, 28 de janeiro de 2009 15:24