PL SQL函数while循环意外结束

时间:2013-04-11 13:53:39

标签: sql function plsql while-loop

我有一个函数,我想计算两个日期之间的秒数,这些秒应该只在我们公司的营业时间内计算。因为完成任务可能需要几天时间我创建了一个应该增加日期的while循环

这是我的循环:

    WHILE TO_DATE(TRUNC(dateIterator),'YYYY-MM-DD') < TO_DATE(TRUNC(CallbackUpdatedDate),'YYYY-MM-DD') LOOP
 calculateIntervalFrom := null;
calculateIntervalTo := null;

SELECT THIS_DATE_OPENING,
 THIS_DATE_CLOSING,
 NEXT_DATE_OPENING
INTO thisDateOpening, thisDateClosing, nextDay
FROM KS_DRIFT.SYS_DATE_KS
WHERE THIS_DATE = dateIterator;

-- gets calculated from
calculateIntervalFrom := thisDateOpening;

-- Gets calculateTo
IF dateIterator = TO_DATE(TRUNC(CallbackUpdatedDate),'YYYY-MM-DD') THEN
calculateIntervalTo := CallbackUpdatedDate;
ELSE
calculateIntervalTo := thisDateClosing;
END IF;
fromSeconds := abs(extract(second from TO_TIMESTAMP(calculateIntervalFrom))) + extract(minute from TO_TIMESTAMP(calculateIntervalFrom)) * 60 + extract(hour from TO_TIMESTAMP(calculateIntervalFrom)) * 60 * 60;
toSeconds :=abs(extract(second from TO_TIMESTAMP(calculateIntervalTo))) + extract(minute from TO_TIMESTAMP(calculateIntervalTo)) * 60 + extract(hour from TO_TIMESTAMP(calculateIntervalTo)) * 60 * 60;
intervalDifference := fromSeconds - toSeconds;

solvedSeconds := solvedSeconds + intervalDifference;
dateIterator := nextDay;
dbms_output.put_line(nextDay);

一个小解释

所以我的想法是,只要值dateIterator(创建行的日期)与上次更新行(CallbackUpdatedDate)不同,它就会从表KS_DRIFT.SYS_DATE_KS

中选择今天和下一天的营业时间

如果今天的日期与CallbackUpdatedDate相同,则会将calculateIntervalTo设置为等于CallbackUpdatedDate,否则会将值设置为thisDateClosing

然后计算两个日期之间的秒数,并将其添加到NUMBER solvedSeconds

之后,我会将dateIterator设置为下一个开放日:dateIterator := nextDay;

这可以工作但只有两次,然后它只是结束循环:

以下是它计算的两个日期:

创建时间:2013-03-26 10:23:33

上次更新时间:2013-04-03 09:25:10

dbms_output.put_line(nextDay); outputs these two values: 

2013-03-27和 2013年3月27日

从外观上看,似乎while循环中的SELECT语句不能按预期工作,但我根本看不出原因?

2 个答案:

答案 0 :(得分:2)

你如何对待日期看起来很奇怪:

TO_DATE(TRUNC(dateIterator),'YYYY-MM-DD') 

所以dateIterator是你截断的日期,即删除时间部分。这将为您提供时间设置为00:00:00的日期。但是那时你在那个日期使用to_date函数,好像它是一个字符串。这看起来不对我。

然后在你的select语句中

WHERE THIS_DATE = dateIterator

我想知道:上面你必须从dateIterator中剥离时间。在这里,你没有。您的表是否包含dateIterator包含时间部分的条目?

我希望这些发现已经有助于解决问题。

答案 1 :(得分:1)

为什么不使用单个查询,而不是使用WHILE循环?类似的东西:

select (end_date - start_date - 
        (select coalesce(sum(least(NEXT_DATE_OPENING,end_date) -
                             greatest(THIS_DATE_CLOSING,start_date)),0)
         from KS_DRIFT.SYS_DATE_KS
         where THIS_DATE_CLOSING < end_date and 
               NEXT_DATE_OPENING > start_date)) * 86400 available_time
from dual

SQLFiddle here