我有一个函数,我想计算两个日期之间的秒数,这些秒应该只在我们公司的营业时间内计算。因为完成任务可能需要几天时间我创建了一个应该增加日期的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语句不能按预期工作,但我根本看不出原因?
答案 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。