ORA-01849:小时必须在1到12之间

时间:2015-02-26 12:11:30

标签: oracle

WHERE (ResTRRequest.RequestTime BETWEEN TO_CHAR(TRUNC(TO_DATE('2012-12-01 20:10:10', 'HH')), 'YYYY-MM-DD HH24:MI:SS') 
AND TO_CHAR(TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '59:59' MINUTE TO SECOND, 'YYYY-MM-DD HH24:MI:SS'))

当我执行它时,我在查询条件的上方,由于我给出的静态日期,它给我的时间必须介于1到12之间,即' 2012-12-01 20:10: 10',' HH')'如果我把sysdate的工作正常,但由于静态日期,它会给我错误。

5 个答案:

答案 0 :(得分:9)

让我们稍微分解一下:

WHERE (ResTRRequest.RequestTime
  BETWEEN TO_CHAR(TRUNC(TO_DATE('2012-12-01 20:10:10', 'HH')), 'YYYY-MM-DD HH24:MI:SS') 
     AND TO_CHAR(TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '59:59' MINUTE TO SECOND, 'YYYY-MM-DD HH24:MI:SS'))

首先,我认为你不是这个意思:TRUNC(TO_DATE('2012-12-01 20:10:10', 'HH')),我想也许你的意思是:TRUNC(TO_DATE('2012-12-01 20:10:10'), 'HH')。 1-12错误的数字来自于您有一小时的20,并且正在尝试将其转换为掩码为HH的日期。但正如我所说,我认为这是一个错字。您也可以在此使用TIMESTAMP字面而不是TO_DATE()

TRUNC(TIMESTAMP'2012-12-01 20:10:10', 'HH')

其次,只是为了解决这个问题,您是将日期或时间戳存储为字符串吗? 这不是个好主意。

第三,在日期比较中使用BETWEEN并不是一个好主意,因为你可能会错过边缘情况。最好重写如下:

WHERE ( ResTRRequest.RequestTime >= TO_CHAR(TRUNC(TO_DATE('2012-12-01 20:10:10'), 'HH'), 'YYYY-MM-DD HH24:MI:SS') 
    AND ResTRRequest.RequestTime < TO_CHAR(TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '1' HOUR, 'YYYY-MM-DD HH24:MI:SS') )

答案 1 :(得分:3)

问题在掩码中:

TO_DATE('2012-12-01 20:10:10', 'HH')

替换为这个:

TO_DATE('2012-12-01 20:10:10', 'HH24')

答案 2 :(得分:1)

假设ResTRRequest.RequestTime属于日期类型,则此Where子句将起作用:

  where ResTRRequest.RequestTime
BETWEEN TRUNC(TO_DATE('2015-02-26 20:10:10', 'YYYY-MM-DD HH24:MI:SS'), 'HH')
    AND TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '59:59' MINUTE TO SECOND

如果您必须比较字符表示,请记住您按字典顺序进行比较,这意味着字符串的前缀在其字符串之前排序!通过使用相同的格式模型避免引起并发症,其中组合符按重要性递减的顺序排列。 E.g。

 TO_CHAR(<whatever>, 'YYYY-MM-DD HH24:MI:SS')

但不是

 TO_CHAR(<whatever>, 'MM/DD/YYYY HH24:MI:SS')

答案 3 :(得分:0)

在出现此错误的情况下,需要注意的另一件事是数据本身。 我已将日期存储在xml标记中,我必须使用此格式说明符解析并转换为TO_DATE&#39; MM / dd / YYYY HH:MI:SS AM&#39;。 SQL打破&#34; ORA-01849:小时必须介于1到12之间&#34;因为有些记录是这样写的:&#34; 12/20/2017 16:45:00 PM&#34;。注意16h和PM specfier ......

答案 4 :(得分:0)

如果将Oracle的语言设置设置为使用12小时制,则在转换24小时制时将发生此问题。 有两种解决方法:

  1. 在Oracle客户端中转换TIMESTAMP / DATE格式

    更改会话设置nls_timestamp_format ='YYYY-MM-DD HH24:MI:SS.FF6';

  2. 转换查询以匹配24小时格式

    SELECT * FROM TEST_ WHERE DOB> TRUNC(TIMESTAMP'1970-01-01 20:10:10','HH'); 或

    SELECT * FROM TEST_ WHERE DOB> to_date('1970-01-01 20:00:00','YYYY-MM-DD HH24:MI:SS');