Наткнулся сегодня на заметку на Oracle Tips & Tricks со схожим названием. В заметке рассматривается забавный нюанс работы с типом Date в СУБД Oracle. Рассмотрим этот нюанс, так сказать, на русском.
Банальность.
Как многие помнят, большинство сред хранит дату как разницу между этой самой датой и некой опорной датой, в виде числа. Таким образом 01.04.2008-3.111 будет представляться пользователю, конечно, как 28.03.2008 21:20:10, однако храниться дата будет с большей точностью. Т.е. при выполнении действия 01.04.2008-3.111-01.04.2008 мы получим -3.111.
Особенности.
При работе в СУБД Oracle необходимо отметить такие нюансы:
- Числовые типы данных хранятся в десятичном формате.
- Точности большей чем до секунд добиться при использовании типа DATE в СУБД Oracle невозможно.
Вернемся к примеру, описанному выше.
Пример.
SQL> select to_date('01.04.2008')-3.111 from dual;
TO_DATE('01.04.2008')-3.111
---------------------------
28.03.2008 21:20:10
SQL> select to_date('01.04.2008')-3.111-to_date('01.04.2008') from dual;
TO_DATE('01.04.2008')-3.111-TO
------------------------------
-3,11099537037037
Проблема? Нет, особенность!
Рассмотрим 3.111 в виде дельты между датами. Что мы получим?
3.111*24*60*60 = 3 дня 2 часа 39 минут 50.4 секунды
При преобразовании к дате мы теряем те самые 0.4 секунды и получаем дельту3 дня 2 часа 39 минут 50 секунды. Соответственно при обратном пересчете мы получим ((50/60+39)/60+2)/24+3 = 3.11099537037037. Так что вот так.
Будьте аккуратны с неявным преобразованием данных!
Ссылки по теме