quinta-feira, 23 de abril de 2009

Intervalo de Datas no SQL Server

SELECT * FROM ContasReceber WHERE DataVcto BETWEEN '2007-11-10' and '2007-11-10'

Isso pegará todo os lançamentos de 10 de novembro de 2007, certo? Infelizmente, nem sempre é assim e você acaba tendo um Sistema que não é confiável.

Quando existe uma porção de hora, como no exemplo abaixo, a última data do intervalo da SELECT não é considerada, excluindo o registro da consulta.
2007-11-10 08:00:00.000

Pesquisando no Google, achei um ótimo artigo com várias soluções para esse problema, dentre as quais a que achei mais viável é esta função:
CAST(FLOOR(CAST(DataVcto AS FLOAT))AS DATETIME)

Vamos estudar os 3 componentes dessa função simples e genial?
O primeiro
CAST(DataVcto AS FLOAT) converte a data num número.
39394,3333333333

O que vem depois da vírgula é a parte da hora. Veja que 8 horas é um terço de um dia, o que corresponde exatamente ao ,
3333333333.

A segunção função,
FLOOR, arredonda o número:
FLOOR(CAST(DataVcto AS FLOAT))
Se você consultar a ajuda dessa função (eu só uso o Google) você verá que ela arredonda sempre para o inteiro mais baixo, assim você não tem que se preocupar se passar de ,5.
39394

Esse número inteiro é justamente a data sem a parte da hora.
E agora você já entendeu, né? Basta pegar esse número arredondado de fracionário para inteiro e converter para data de novo.
CAST(FLOOR(CAST(DataVcto AS FLOAT))AS DATETIME)
Dessa forma, 2007-11-10 08:00:00.000 fica 2007-11-10 00:00:00.000

Então, a SELECT acima precisa ser reescrita, ficando assim:
SELECT * FROM ContasReceber WHERE CAST(FLOOR(CAST(DataVcto AS FLOAT))AS DATETIME) BETWEEN '2007-11-10' and '2007-11-10'

Esse é um detalhe crucial para ser cuidado se você quiser ter um sistema confiável.


Por isso, que programação é para louco. Pessoas normais não servem para essa profissão.




Nenhum comentário:

Postar um comentário