2013-06-04 2 views
1

В запросах, которые я натыкаюсь на каждую дату, преобразуется функцией to_date перед любым сравнением. Иногда это вызвано «буквальная не соответствует строке формата» ошибка, которая не имела скорее ничего общего с форматом и причина здесь была объяснено: ORA-01861: literal does not match format stringOracle - Должен ли я конвертировать даты с to_date перед сравнением?

Моим вопрос: действительно ли необходимо использовать преобразование даты? Почему он сначала преобразуется, прежде чем применять какое-либо логическое сравнение?

+2

Пожалуйста, покажите нам запрос, который генерирует ошибку и определения таблиц связанных таблиц. –

ответ

3

В Oracle нет данных о датах, ну, датах. Проблема в том, что на датах может быть время, которое может привести к их неравномерности. (Информацию о типе даты можно найти в документации here.)

В целом мы считаем, что «2013-01-01» соответствует «2013-01-01». Однако первая дата может быть «2013-01-01 01:00:00» и вторая «2013-01-01 02:02:02». И они не были бы равными. Хуже того, они могут выглядеть одинаково, когда они распечатываются.

Вам действительно не нужно преобразовывать даты в строки, чтобы выполнять такие сравнения. Вы также можете использовать функцию trunc(). Такое преобразование данных - это страхование от «невидимых» компонентов времени данных, мешающих сравнениям.

0

Если у вас есть строку что представляет дату, используйте TO_DATE.
Если у вас уже есть дата, используйте ее напрямую.

+0

У меня есть подзапрос (используется для соединения), где дата конвертируется с помощью to_char, а затем в родительском запросе используется в where where и преобразуется с помощью to_date. – kyooryu

+2

@kyooryu: Почему вы конвертируете его с 'to_char' в первую очередь? –

+2

@kyooryu, если у вас есть конкретный пример, который поднимает вопрос, было бы лучше разместить его как часть вопроса. –

1

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

select to_date('123', 'MM-DD-YYYY') from dual; 

выдает ORA-01861. Таким образом, у вас может быть 99,9% строк в виде ММ-ДД-ГГГГ, но 0,1% вызовут головные боли.

В любом случае, если вы очищаете эти строки, вы можете сделать гораздо больше, используя функции to_date и date. Например:

select 
(last_day(to_date('02-05-2009', 'MM-DD-YYYY')) - to_date('01-15-1998', 'MM-DD-YYYY')) as days_between_dates 
from dual; 

Не забава сделать это со строками. Или, возможно, просто найти самую последнюю дату:

select greatest(to_date('02-05-2009', 'MM-DD-YYYY'), to_date('12-01-1988', 'MM-DD-YYYY')) from dual; 

с помощью сравнения строк даст неправильный ответ:

select greatest('02-05-2009', '12-01-1988') from dual; 

лишь несколько примеров, но гораздо лучше лечить даты как даты, а не строк.

Смежные вопросы