Я использую тип данных Oracle и обучаю разработчиков вопросам временных компонентов, влияющих на граничные условия.
Ограничение базы данных также предотвратит случайное указание компонента времени в столбце, который не должен иметь ни одного, а также сообщит оптимизатору, что ни одно из значений не имеет компонента времени.
Например, ограничение CHECK (MY_DATE = TRUNC (MY_DATE)) предотвращает помещение значения со временем, отличным от 00:00:00, в столбец my_date, а также позволяет Oracle выводить, что предикат, такой как MY_DATE = TO_DATE ('2008-09-12 15:00:00') никогда не будет иметь значение true, и, следовательно, строки не будут возвращены из таблицы, поскольку она может быть расширена до:
MY_DATE = TO_DATE('2008-09-12 15:00:00') AND
TO_DATE('2008-09-12 15:00:00') = TRUNC(TO_DATE('2008-09-12 15:00:00'))
Это автоматически ложно, конечно.
Хотя иногда бывает заманчиво хранить даты в виде чисел, например 20080915, это может вызвать проблемы с оптимизацией запросов. Например, сколько допустимых значений существует между 20 071 231 и 20 070 101? Как насчет дат 31 декабря 2007 года и 1 января 2008 года? Он также позволяет вводить недопустимые значения, такие как 20070100.
Итак, если у вас есть даты без компонентов времени, определение диапазона становится простым:
select ...
from ...
where my_date Between date '2008-01-01' and date '2008-01-05'
При наличии компонента времени вы можете выполнить одно из следующих действий:
select ...
from ...
where my_date >= date '2008-01-01' and
my_date < date '2008-01-06'
или
select ...
from ...
where my_date Between date '2008-01-01'
and date '2008-01-05'-(1/24/60/60)
Обратите внимание на использование (1/24/60/60) вместо магического числа. В Oracle довольно распространено выполнение арифметики дат путем добавления определенных долей дня ... 3/24 в течение трех часов, 27/24/60 в течение 27 минут. Математика Oracle этого типа точна и не имеет ошибок округления, поэтому:
select 27/24/60 from dual;
... дает 0,01875, а не 0,01874999999999 или что-либо еще.