Найти тему
Илья Хохлов

Неявные ошибки в SQL запросах

Проверяя работу наших учеников курса "SQL. Базы данных. ORACLE", и даже курса "Программирования в PL/SQL (ORACLE)" иногда встречаю следующее использование функции to_date, которое содержит ошибку. И сейчас напишу почему. Итак, вот конструкция, содержащая ошибку:

to_date(sysdate, 'dd.mm.yyyy')

Функция to_date служит для преобразования ТЕКСТА в дату согласно указанной маске, а в примере выше функции на вход даётся итак дата (sysdate ведь дата, только ещё и со временем). Во-первых, неразумно из итак даты делать дату, иначе будет как в мультфильме про Кунг-фу панду:

-Ты не должен делать из них себя, ты должен делать из них их;

-Как я могу делать из них их, если они итак уже они? :)

Почему же эта конструкция ещё и содержит ошибку. Ошибка в том, что в этой конструкции Ораклу придётся задействовать неявное преобразование.

Чтобы функция to_date смогла отработать, она должна принять на вход ТЕКСТ и преобразовать его в дату, согласно указанной маске. А в примере выше Ораклу подаётся дата, ведь sysdate это итак дата (текущая, со временем). И Оракл сначала неявно преобразовывает ее в текст, а вот как он это выполняет без указанной макси преобразования, может зависеть от региональных настроек представления даты. В итоге дата в текст может быть преобразована совсем другая (будет другой день, месяц или год). И уже из текста, в котором может быть совершенно неожиданно другая дата, to_date сделает дату согласно указанной маске. Результат может быть неожиданным.

Неявного преобразования всегда нужно избегать. Это может привести к скрытым ошибкам. Все работает (ORACLE не показывает ошибку), а данные в результате в самый неподходящий и ответственный момент будут получены не правильные.

Я обычно всегда спрашиваю ученика для чего такая конструкция была сделана и что требовалось здесь получить. В итоге, чаще всего, нужна бывает текущая дата без времени. Текущую дату со временем в ORACLE даёт функция SYSDATE, и чтобы отбросить у неё часы, минуты и секунды (то есть чтобы сделать ее просто датой), можно обернуть её в функцию trunc. Функция trunc сделает из неё дату без времени (усечёт часы, минуты и секунды). То есть конструкцию:

to_date(sysdate, 'dd.mm.yyyy')

лучше заменить на:

trunc(sysdate).

Буду рад лайку этой статье и твоей подписке на мой канал, если ты еще не подписан.

Если есть Telegram, подписывайся на наш канал в Телеграмме. Несколько раз в неделю решаем вместе разные задачи по SQL, и ещё помогаю не выпадать из темы айти. Делюсь полезной информацией и техническим-юмором:)

А здесь ты можешь пройти наш курс обучения языку SQL и получить мощные знания и умения! Всего за 27 уроков до уровня специалиста, имеющего трёхлетний стаж. Много практики в реальной базе данных! С нашей поддержкой и проверкой твоих самостоятельный задач! Записывайся, буду тебя ждать!