这是我的Oracle查询,它根据日期差异应为一个月的日期获取记录:
select *
from pbxhbl.HBL_TRANSACTIONS
where dat_creation between '10-apr-2013' and '10-jun-2013'
and MONTHS_BETWEEN('10-jun-2013','10-apr-2013') = 1
我的问题是,当差异超过一个时,我想要显示一条消息:
'日期持续时间应为一个月
答案 0 :(得分:0)
MONTHS_BETWEEN(' 10君-2013',' 10-APR-2013&#39)
首先,'10-jun-2013'
不是 DATE ,而是 STRING 。 Oracle将进行隐式数据类型转换。请避免这种情况,并始终使用 TO_DATE 将字符串显式转换为日期。
其次,您发布的两个日期之间的月份永远不会为1 ,将始终为2 。
SQL> SELECT MONTHS_BETWEEN(to_date('10-jun-2013','dd-mon-yyyy'),to_date('10-apr-2013','dd-mon-yyyy')) dt
2 FROM dual;
DT
----------
2
SQL>
因此,理想情况下,您的查询将始终不返回任何行。
SQL> SELECT *
2 FROM dual
3 WHERE MONTHS_BETWEEN(to_date('10-jun-2013','dd-mon-yyyy'),to_date('10-apr-2013','dd-mon-yyyy')) =1;
no rows selected
SQL>
回到你的问题,
您可以使用 CASE 表达式。
但是,如果您要过滤掉行,那么您将无法显示任何内容。因此,请删除过滤器,以便每当MONTHS_BETWEEN
的值大于1时,您都可以返回该消息。
例如,
SQL> WITH DATA AS(
2 SELECT to_date('01-03-2015','DD-MM-YYYY') dt1, to_date('01-04-2015','DD-MM-YYYY') dt2 FROM dual UNION ALL
3 SELECT to_date('01-03-2015','DD-MM-YYYY') dt1, to_date('10-04-2015','DD-MM-YYYY') dt2 FROM dual UNION ALL
4 SELECT to_date('01-03-2015','DD-MM-YYYY') dt1, to_date('01-05-2015','DD-MM-YYYY') dt2 FROM dual
5 )
6 SELECT DT1,
7 DT2,
8 CASE
9 WHEN months_between(dt2, dt1) >1
10 THEN 'date duration should be one month'
11 ELSE 'OK'
12 END MESSAGE
13 FROM DATA;
DT1 DT2 MESSAGE
--------- --------- ---------------------------------
01-MAR-15 01-APR-15 OK
01-MAR-15 10-APR-15 date duration should be one month
01-MAR-15 01-MAY-15 date duration should be one month
SQL>
答案 1 :(得分:0)
您需要在功能内完成所需。
创建一个函数,它将两个参数作为输入(date, date)
,并作为输出返回表类型的记录。
在函数内部,在将查询传递给输出之前,插入一个条件控制结构,如CASE
或IF
,以检查给定日期是否符合您的条件。如果是,只需将查询传递给结果,如果没有(假设您希望有人在应用程序中看到它),则返回一个查询,该查询与您通常返回的记录一样,并将消息包含在列中的一列中。休息应该保持NULL
。
对于上述情况,我认为提出错误不是你真正需要的。
伪代码:
CREATE FUNCTION check_dates_for_hbl_transactions(date, date)
RETURNS record
AS $function$
BEGIN
IF ( MONTHS_BETWEEN( $1 - $2 ) > 1 )
THEN RETURN QUERY SELECT 'Date duration should be one month at max'::text, NULL::bigint, ...
ELSE
RETURN QUERY SELECT * FROM HBL_TRANSACTIONS WHERE dat_creation BETWEEN $1 AND $2
END IF;
END
$function$
重要提示:我写'message'::text, NULL::bigint, ...
的原因是为了表明您的select语句必须与返回的集匹配(在这种情况下,表{{1}中的所有列及其类型})。
另外,请考虑为日期$ 2添加额外支票,使其大于日期$ 1参数。
旁注:考虑返回rowtype以使其更容易。我不喜欢这种方法,因为在行类型被更改的情况下它容易出错。我宁愿让失败的功能和手动检查原因,而不是像往常一样正常通过错误的值。