Странное поведение при фильтрации по дате в Oracle

Я в базе данных Oracle, следующий запрос:

select codi_belf, data_elab,id_inte,anno from mimsspam_tab where id_inte = 504;

извлекает 6 записей

E924    05-AGO-15   504 2015
D458    05-AGO-15   504 2015
D458    05-AGO-15   504 2015
B275    05-AGO-15   504 2015
E924    05-AGO-15   504 2015
B275    05-AGO-15   504 2015

где «data_elab» — ​​это поле типа DATE, а AGO — это просто итальянская локаль для AUG.

Я пытаюсь фильтровать по дате следующим образом:

select codi_belf, data_elab,id_inte,anno 
from mimsspam_tab where id_inte = 504 
and data_elab = TO_DATE('05/08/2015','dd/MM/yyyy');

И у меня НЕТ результатов..

Более того, если я фильтрую таким образом:

select codi_belf, data_elab,id_inte,anno  
from mimsspam_tab where id_inte = 504 
and TO_CHAR(data_elab,'dd/MM/yyyy')='05/08/2015';

Я вернул свои шесть пластинок!

Разве два способа фильтрации не должны быть эквивалентны? Почему это не так? И почему первый съедает все мои шесть записей? Может ли это зависеть от странной конфигурации установки оракула, к которой я обращаюсь?


person Tito Zoe Chiacchiera    schedule 05.08.2015    source источник
comment
В вашем выборе используйте to_char для этой даты с форматом, который включает часы и минуты.   -  person Mat    schedule 05.08.2015
comment
Возможный дубликат этого или этого или многие другие.   -  person Alex Poole    schedule 05.08.2015


Ответы (2)


То, что вы видите в своем первом запросе, — это формат даты по умолчанию для вашей базы данных, определяемый вашими параметрами NLS. Ваше поле даты на самом деле содержит информацию о времени, просто вы ее не видите.

Во втором запросе, когда вы используете to_date(), вы конвертируете string в date и не предоставляете информацию о времени, поэтому вы получаете 00:00:00 для временной части вашего date. Сравнение его с вашим полем (которое включает информацию о времени) не приведет к совпадению.

В третьем запросе, когда вы используете to_char(), вы преобразуете поле даты в string, которое не включает информацию о времени. Сравнивая его с вашим литералом string, вы получаете совпадающие записи.

Попробуйте представить поле даты как двоичную информацию, а не как строку символов. Старайтесь не полагаться на параметры базы данных по умолчанию.

person Erkan Haspulat    schedule 05.08.2015
comment
И @Boneist, и вы правы. Если я выберу to_char(data_elab,'dd/mm/yyyy hh:mm:ss') из таблицы, я смогу увидеть информацию о времени, например, 08.05.2015 11:08:31 - person Tito Zoe Chiacchiera; 05.08.2015

Похоже, что в вашем столбце data_elab есть элементы времени, из-за которых ваш параметр nls_date_format по умолчанию не отображается при выборе этого столбца.

Если в data_elab нет индекса, то следующее должно вернуть вам строки:

and trunc(data_elab) = TO_DATE('05/08/2015','dd/MM/yyyy');

Если в data_elab есть индекс, и вы хотите, чтобы он использовался, то должно работать следующее:

and data_elab >= TO_DATE('05/08/2015','dd/MM/yyyy')
and data_elab < TO_DATE('06/08/2015','dd/MM/yyyy')
person Boneist    schedule 05.08.2015