2014-05-14 29 views
1

我在Oracle中有一个函数,用于检查第一个日期是否包含第二个日期。它没有问题,因为[a, b]包含[x, y],如果x => a and y <= b and x <= y。适用于定义的start/end date 1start/end date 2。但现在我想修改它。如果任何给定的“开始”日期为NULL,则应将其视为+-infinite包含无限间隔的日期范围

这是一个代码:

FUNCTION CONTAINS(p_START_DATE_1 DATE, p_END_DATE_1 DATE, 
    p_START_DATE_2 DATE, p_END_DATE_2 DATE) RETURN VARCHAR2 AS 

    lv_RESULT VARCHAR2(1); 
    BEGIN 
     lv_RESULT := 'N';  

     IF (/* milions of conditions here */) THEN 
     lv_RESULT := 'Y'; 
     END IF; 

     RETURN lv_RESULT; 
    END CONTAINS; 

例如:假设p_START_DATE_1NULL。在这种情况下,该代码:

SELECT MY_PACKAGE_SQL.CONTAINS(
     NULL, 
     TO_DATE('01/12/2014', 'DD/MM/YYYY'), 
     TO_DATE('01/02/2012', 'DD/MM/YYYY'), 
     TO_DATE('01/05/2012', 'DD/MM/YYYY')) 
FROM DUAL; 

...应该返回Y,因为第一个日期范围为(-infinite, 01/12/2014],它包含[01/02/2012, 01/05/2012]

现在我的问题...我知道我可以使用额外的"IFs"来检查NULLs。但我想知道是否有其他解决方案使其在Oracle's PL\SQL语言中更快?这就像do it in smarter way challenge在我的球队:)

+0

你可以使用'p_start_date_1:= coalesce(p_start_date_1,p_start_date_2,1)'和'p_start_date_2:= coalesce(p_start_date_2,p_start_date_1,1)'etc? (1可能需要是实际的低价值日期)。类似的上限。 – Turophile

回答

1

如果只有日期不能为空你可以把它像:

IF ((p_END_DATE_1 >= p_START_DATE_2) AND 
     (p_START_DATE_1 <= p_END_DATE_2)) THEN 
    lv_RESULT := 'Y'; 
    END IF; 

的零位你可以声明,说

-Infinity == 1 Jan 1 
    +Infinity == 31 Dec 3999 

所以在CoalesceNvl函数的帮助下,您可以实现

IF (coalesce(p_END_DATE_1, TO_DATE('31.12.3999', 'dd.mm.yyyy')) >= 
     coalesce(p_END_DATE_2, TO_DATE('31.12.3999', 'dd.mm.yyyy')) AND 
     coalesce(p_START_DATE_1, TO_DATE('1.1.1', 'dd.mm.yyyy')) <= 
     coalesce(p_START_DATE_2, TO_DATE('1.1.1', 'dd.mm.yyyy'))) THEN 
    lv_RESULT := 'Y'; 
    END IF; 
+0

谢谢你,先生:)作为一个梦想 – Nickon

相关问题