在 Oracle 中按日期过滤时的奇怪行为
Strange behaviour when filtering by date in 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';
我找回了我的六张唱片!
这两种过滤方式不应该是等价的吗?为什么他们不是?为什么第一个吃掉了我所有的六个记录?
这可能取决于我要查询的 oracle 安装的奇怪配置吗?
您在第一个查询中看到的是您的数据库默认日期格式,由您的 NLS 参数决定。您的日期字段实际上包含时间信息,只是您看不到而已。
在你的第二个查询中,当你使用 to_date()
时,你将 string
转换为 date
并且不提供时间信息,所以你得到 00:00:00
在你 date
的时间部分。将其与您的字段(包括时间信息)进行比较将导致不匹配。
在您的第三个查询中,当您使用 to_char()
时,您将日期字段转换为不包含时间信息的 string
。将它与您的文字 string
进行比较,您会得到匹配的记录。
尝试将日期字段视为二进制信息,而不是字符串。尽量不要依赖数据库默认参数。
听起来您的 data_elab 列包含您的默认 nls_date_format 设置导致在您 select 该列时不显示的时间元素。
如果 data_elab 上没有索引,那么下面应该 return 你的行:
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')
我在 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';
我找回了我的六张唱片!
这两种过滤方式不应该是等价的吗?为什么他们不是?为什么第一个吃掉了我所有的六个记录? 这可能取决于我要查询的 oracle 安装的奇怪配置吗?
您在第一个查询中看到的是您的数据库默认日期格式,由您的 NLS 参数决定。您的日期字段实际上包含时间信息,只是您看不到而已。
在你的第二个查询中,当你使用 to_date()
时,你将 string
转换为 date
并且不提供时间信息,所以你得到 00:00:00
在你 date
的时间部分。将其与您的字段(包括时间信息)进行比较将导致不匹配。
在您的第三个查询中,当您使用 to_char()
时,您将日期字段转换为不包含时间信息的 string
。将它与您的文字 string
进行比较,您会得到匹配的记录。
尝试将日期字段视为二进制信息,而不是字符串。尽量不要依赖数据库默认参数。
听起来您的 data_elab 列包含您的默认 nls_date_format 设置导致在您 select 该列时不显示的时间元素。
如果 data_elab 上没有索引,那么下面应该 return 你的行:
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')