我正试图编写一个BeforeReport触发器,用于检查用户是否在创建后120秒内访问了报告数据。
我的代码如下:
function BeforeReport return boolean is
ENTRYDATE TIMESTAMP;
SERVERDATE TIMESTAMP;
DIFFSECONDS NUMBER;
begin
/*Checks to see if user is accessing the data within 120 seconds of creation in database*/
VALIDTIMELENGTH := 120;
SELECT SYS_DATE INTO ENTRYDATE FROM WOS_REPORT_PARAM WHERE SEQUENCE_NUM=UPPER(:SEQUENCENUM) AND PARAMETER='year';
SERVERDATE := CURRENT_TIMESTAMP;
DIFFSECONDS := ((EXTRACT(YEAR FROM ENTRYDATE)- EXTRACT(YEAR FROM SERVERDATE))*31536000) +
((EXTRACT(MONTH FROM ENTRYDATE)- EXTRACT(MONTH FROM SERVERDATE))*2592000) +
((EXTRACT(DAY FROM ENTRYDATE) - EXTRACT(DAY FROM SERVERDATE))*86400) +
((EXTRACT(HOUR FROM ENTRYDATE) - EXTRACT(HOUR FROM SERVERDATE))*3600) +
((EXTRACT(MINUTE FROM ENTRYDATE) - EXTRACT(MINUTE FROM SERVERDATE))*60) +
(EXTRACT(SECOND FROM ENTRYDATE) - EXTRACT(SECOND FROM SERVERDATE));
IF DIFFSECONDS > VALIDTIMELENGTH THEN RETURN(FALSE);
ELSE
return (TRUE);
END IF;
END;
问题是,无论经过多少时间,我的代码似乎都会返回true。我是否没有正确实现秒/分钟代码?奇怪的是,我尝试了两个返回(FALSE),但它仍然通过了报告!甲骨文的报告前后矛盾,令人愤怒。我们非常感谢您的回复。
如果wos_report_param.sys_date
是TIMESTAMP
(请注意,当有返回DATE
的sysdate
函数时,将列命名为sys_date
相当令人困惑),并且假设wos_report_param.sys_date
是过去的时间戳,那么您的逻辑可以简化很多
IF( current_timestamp - entrydate > numtodsinterval( validTimeLength, 'second' ) )
THEN
RETURN true;
ELSE
RETURN false;
END IF;
如果我的猜测是正确的,并且wos_report_param.sys_date
是过去的时间戳,那么你正在计算的diffseconds
将是一个负数,这解释了为什么你的过程总是返回false
。您需要从较晚的日期中减去较早的日期,以产生正的间隔,而不是负的间隔。或者,您可以在计算diffseconds
时抛出一个abs
。