Usuário com melhor resposta
Filtrar datas

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 SnippetSELECT
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.
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 SnippetSELECT
CodHistorico, DataHistoricoFROM
TB_HistoricoWHERE
CodAparelho = @CodAparelhoAND
(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
-
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 SnippetscmHistorico.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 SnippetscmHistorico.Parameters.AddWithValue("@DataInicio", dataInicio);
scmHistorico.Parameters.AddWithValue("@DataFim", dataFim);
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 SnippetSELECT
CodHistorico, DataHistoricoFROM
TB_HistoricoWHERE
CodAparelho = @CodAparelhoAND
(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
-
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 SnippetscmHistorico.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 SnippetscmHistorico.Parameters.AddWithValue("@DataInicio", dataInicio);
scmHistorico.Parameters.AddWithValue("@DataFim", dataFim);
-
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
-
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.
-
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