Oracle中日期,时间,时间戳或间隔文字的格式错误

问题描述 投票:0回答:2

我试图检查我当前的时间戳是否落在两次邮票之间。

我在Oracle StoredProcedure中使用以下查询

IF(SYSDATE BETWEEN TRUNC ( SYSDATE ) + INTERVAL '17:50' HOUR TO MINUTE AND TRUNC( SYSDATE ) + INTERVAL '18:30' HOUR TO MINUTE) THEN 

但它给了我以下错误

Error(138,42): PLS-00166: bad format for date, time, timestamp or interval literal

我错过了什么吗?

oracle plsql date-arithmetic
2个回答
2
投票

trunc(sysdate)是一个日期,而不是时间戳。不幸的是,Oracle这种方式很奇怪:日期算术使用数字(仅限数字),而时间戳则使用间隔。您无法在(日期)日期之间添加或减去间隔。

更糟糕的是:trunc(systimestamp)是DATE而不是TIMESTAMP!如果你想知道原因,你将不得不问Oracle;我不知道为什么。

解决方案很简单。而不是interval '17:50' hour to minute,添加17/24 + 50/(24*60)

或者,您可以将trunc(sysdate)投射到时间戳:cast(trunc(sysdate) as timestamp) - 然后其余的应该工作。

增加:正如OP指出的那样,将sysdate转换为时间戳并没有解决问题。我再次尝试使用不同的INTERVAL文字。虽然INTERVAL '17:50' HOUR TO MINUTE不起作用,但完整格式的INTERVAL '0 17:50:00' DAY TO SECOND确实有效(!!!)似乎PL / SQL无法识别部分INTERVAL格式并且需要完整的DAY TO SECOND。要检查PL / SQL定义/文档的东西。

...确定,在进一步检查Oracle文档之后:没有特别提及不支持HOUR TO MINUTE;但它没有出现在任何地方。只提到了第二天。 (一般来说,文档只会显示实现的内容,而不是未实现的内容,所以这在任何方面都不奇怪。)


0
投票

在PLSQL中,只能使用DAY TO SECOND。您可以使用以下之一:

begin
    IF(SYSDATE BETWEEN TRUNC(SYSDATE) + INTERVAL '0 16:00:00' DAY TO SECOND
                     AND TRUNC(SYSDATE) + INTERVAL '0 18:00:00' DAY TO SECOND
    --IF(SYSDATE BETWEEN TRUNC(SYSDATE) + to_dsinterval('0 16:00:00')
    --               AND TRUNC(SYSDATE) + to_dsinterval('0 18:00:00')
    )
    THEN
            dbms_output.put_line('now:'||sysdate); --now:01.03.2018 16:41:07
    end if;
end;
/

请考虑以下事项:

SQL

select interval '0 4'       day to hour  as ci from dual;          --+00 04:00:00.000000

select interval '0 4:10'    day to minute  as ci from dual;       --+00 04:10:00.000000

select interval '4:10'      hour to minute  as ci from dual;      --+00 04:10:00.000000

select interval '4:10:15'   hour to second  as ci from dual;      --+00 04:10:15.000000

select interval '0 4:10:15' day  to second as ci  from dual;       --+00 04:10:15.000000

PLSQL

declare

  --ci  CONSTANT INTERVAL DAY TO SECOND := interval '0 4'       day to  hour;      --PLS-00103

  --ci  CONSTANT INTERVAL DAY TO SECOND := interval '0 4:10'    day to  minute;    --PLS-00166

  --ci  CONSTANT INTERVAL DAY TO SECOND := interval '4:10'      hour to  minute;   --PLS-00166  

  --ci  CONSTANT INTERVAL DAY TO SECOND := interval '4:10:15'   hour to  second;   --PLS-00166  

  ci  CONSTANT INTERVAL DAY TO SECOND := interval '0 4:10:15' day to  second;    --[+00 04:10:15.000000] 

begin 
  dbms_output.put_line('['||ci||']'); 
end;
/
--PLS-00166:  bad format for  date, time, timestamp or interval literal
--PLS-00103:  Encountered the symbol "HOUR" when expecting  one of the  following: second
© www.soinside.com 2019 - 2024. All rights reserved.