Oracle

时间:2017-06-15 17:18:56

标签: oracle plsql date-arithmetic

我正在尝试检查我当前的时间戳是否介于两次邮票之间。

我在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

我错过了什么吗?

2 个答案:

答案 0 :(得分: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) - 其余部分应该有效。

ADDED :正如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;但它没有出现在任何地方。只提到了第二天。 (一般来说,文档只会显示实现的内容,而不是未实现的内容,所以这并不奇怪。)

答案 1 :(得分: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