2014-05-14 32 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

相關問題