Oracle sql日期时间戳过滤器

时间:2018-04-06 23:06:24

标签: oracle

我的Oracle表有以下2个变量的1,000个观察值:(两个字段都是varchar)

ID   datecreate
ABC  24/12/2016 05:32:07

我想过滤日期。我试过以下但无济于事......

select *
from table
where datecreate >= to_date('01/02/2018 00:00:00', 'dd/mm/yyyy hh24:mi:ss') and
datecreate <= to_date('28/02/2018 23:59:00', 'dd/mm/yyyy hh24:mi:ss')

我一直收到以下错误......

ORA-01843: not a valid month
01843. 00000 -  "not a valid month"
*Cause:    
*Action:

我错过了一些明显的东西吗?

由于

2 个答案:

答案 0 :(得分:2)

默认NLS_DATE_FORMAT目前是DD-MON-RR。因此,定义为字符串的datecreate列将隐式转换为该格式。值12与DEC不同,因此出错。要么使用正确的格式,要么将其转换为类似于下面的日期。

select *
from tbl
where to_date(datecreate, 'dd/mm/yyyy hh24:mi:ss') >= 
to_date('01/02/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss')
and to_date(datecreate, 'dd/mm/yyyy hh24:mi:ss') <= 
to_date('28/02/2018 23:59:00', 'dd/mm/yyyy hh24:mi:ss')

答案 1 :(得分:2)

多次强调,在数据库中,DATETIME不应存储为字符串。然而,每天都会提出几个问题,这完全是由于这种不良做法造成的。

请注意,在Oracle中,日期时间可以存储为DATE类型或TIMESTAMP(带或不带TIMEZONE)。 DATE类型也包含时间组件。

在必须处理日期字符串进行转换的情况下,

TO_DATE函数可以解决问题。在使用日期时,最好使用DATE格式的标准'YYYY-MM-DD'文字,这是大多数DBMS所理解的。 (例如: - DATE '2018-02-28')。

此外,当您可以使用'28/02/2018 23:59:00'文字时,不需要对此类边界情况使用TRUNCDATE函数。因此,您的查询可以重写为

SELECT *
FROM   yourtable
WHERE  TO_DATE(datecreate, 'dd/mm/yyyy hh24:mi:ss') >= DATE '2018-02-01'
   AND TO_DATE(datecreate, 'dd/mm/yyyy hh24:mi:ss')  < DATE '2018-02-28' + 1 

< DATE '2020-02-29'如果您知道这是闰年。

如果您真的要考虑到23:59分钟,那么TIMESTAMP文字可以与TO_TIMESTAMP函数一起使用。

.. AND  TO_TIMESTAMP(datecreate, 'dd/mm/yyyy hh24:mi:ss') <
        TIMESTAMP '2018-02-28 23:59:00'