比较日期和时间戳与BETWEEN子句

时间:2017-05-22 14:37:53

标签: oracle

我的查询的基本结构是:

SELECT....FROM....
WHERE SYSTIMESTAMP BETWEEN DateA and DateB.

我正在尝试各种各样的方法,其中之一就是,但是得到的错误就像 ORA-01861:文字与格式字符串OR不匹配,在某些情况下“不是有效月份”

WHERE
SYSTIMESTAMP BETWEEN 
      TO_TIMESTAMP(TO_DATE(DateA,'YYYY-MM-DD HH24:MI:SS'),  'DD/MM/YYYY HH24:MI:SSFF') AND 
      TO_TIMESTAMP(TO_DATE(DateB,'YYYY-MM-DD HH24:MI:SS'),  'DD/MM/YYYY HH24:MI:SSFF') 

DateA和DateB列的类型为DATE,SYSTIMESTAMP显然是TIMESTAMP。

我的SQL开发人员的NLS设置是

  • 日期:'MM/DD/YYYY HH24:MI:SS'
  • 对于TIMESTAMP:'DD-MON-RR HH.MI.SSXFF AM'

请帮我确定问题。

3 个答案:

答案 0 :(得分:1)

TO_TIMESTAMPTO_DATE都使用指定的格式掩码取一个字符串并将其转换为时间戳/日期。

因此,执行TO_TIMESTAMP(TO_DATE(..)...)没有意义 - 特别是当您的原始列已经采用日期格式时!你需要一个或另一个。

通过执行TO_TIMESTAMP(TO_DATE(<date_column>..)...),您正在做的是强制oracle从日期到字符串执行一些隐式转换,然后返回到日期然后返回到字符串,以便可以将其转换回来进入时间戳。看起来像这样:

TO_TIMESTAMP(TO_CHAR(TO_DATE(TO_CHAR(<date_column>, <nls_date_format>), <your_date_format>), <nls_date_format>), <your_timestamp_format>).

这太复杂了,对吧?另外,如果其中一种格式不匹配,那么您将收到您遇到的错误。

如果要将DATE转换为TIMESTAMP,可以使用CAST,例如:

where systimestamp between cast(datea as timestamp) and cast(dateb as timestamp)

或者你可以让Oracle处理从日期到时间戳的隐式转换,然后执行:

where systimestamp between datea and dateb

或者完全通过使用sysdate而不是systimestamp来避免这个问题,即:

where sysdate between datea and dateb

答案 1 :(得分:0)

您无需转换即可timestampdate进行检查;例如:

SQL> desc testDate
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 DATEA                                              DATE
 DATEB                                              DATE

SQL> select * from testDate;

DATEA     DATEB
--------- ---------
21-MAY-17 23-MAY-17
19-MAY-17 21-MAY-17

SQL> select *
  2  from testDate
  3  where systimestamp between dateA and dateB ;

DATEA     DATEB
--------- ---------
21-MAY-17 23-MAY-17

SQL>

答案 2 :(得分:0)

如果您已经使用DATE格式,则无需转换为时间戳。只需使用:

WHERE SYSTIMESTAMP BETWEEN DateA AND DateB