2017-04-26 127 views
0

我有一個SQL查詢,投2個日期,並檢查它們是否相等。但即使日期是平等的,我沒有得到結果。函數獲得兩個日期之間的平日數除外假期

create or replace 
FUNCTION getWorkingDays(
    DATE_ONE DATE, 
    DATE_TWO DATE) 
RETURN NUMBER 
IS 
DAY_COUNT NUMBER := 0; 
START_DATE DATE; 
END_DATE DATE; 
HOL_COUNT NUMBER := 0; 
BEGIN   
IF(DATE_ONE     IS NOT NULL AND DATE_TWO IS NOT NULL) THEN 
    IF DATE_ONE     < DATE_TWO THEN 
    START_DATE    := DATE_ONE; 
    END_DATE     := DATE_TWO; 
    ELSE 
    START_DATE := DATE_TWO; 
    END_DATE := DATE_ONE; 
    END IF;  
    WHILE START_DATE < END_DATE  
    LOOP  
    IF TO_CHAR(START_DATE,'DY') NOT IN ('SAT','SUN') THEN 
     DAY_COUNT := DAY_COUNT   + 1; 
    END IF;  
    SELECT count(*) INTO HOL_COUNT 
FROM ATL_JOB_HOLIDAY jh 
JOIN ATL_MASTER_JOB mj 
ON MJ.MASTER_JOB_ID  = JH.MASTER_JOB_ID 
WHERE TRUNC(HOLIDAY_DATE) = START_DATE; 
    IF(HOL_COUNT >0) THEN 
     DAY_COUNT := DAY_COUNT   + 1; 
     Dbms_Output.put_line('Holiday333 :- IS A HOLIDAY'); 
     END IF; 
     START_DATE := START_DATE + 1;  
    END LOOP; 
END IF; 
RETURN DAY_COUNT; 
EXCEPTION 
WHEN OTHERS THEN 
    RETURN NULL; 
END getWorkingDays;' 
+5

什麼是您的DBMS? 「在SQL中」?什麼SQL?甲骨文? PostgreSQL的? –

+0

ANSI SQL不能將'16 -APR-11'識別爲日期。你使用哪個dbms? – jarlh

回答

0

我猜你正在使用Oracle。如果是這樣,那麼DATE數據類型包含一個時間組件。這很混亂。但是你可以做你想要使用TRUNC()而不是CAST()什麼:

SELECT TRUNC(HOLIDAY_DATE), DATE '2011-04-16' --into DAY_COUNT 
FROM ATL_JOB_HOLIDAY jh JOIN 
    ATL_MASTER_JOB mj 
    ON mj.MASTER_JOB_ID = jh.MASTER_JOB_ID 
WHERE TRUNC(HOLIDAY_DATE) = DATE '2011-04-16'; 

還要注意偏愛ANSI標準日期和表的別名。

+0

這是一個例子。我有這個問題的原始功能是 – Ann

0

你的where子句是這樣的:

where trunc(HOLIDAY_DATE) = to_date('2016-APR-11', 'yyyy-mon-dd') 
0

我貼這個最中你剛纔的問題。您不需要循環查看每個日期並單獨檢查每個日期。你應該能夠計算出一週的天數,然後就減去你的表的不同天數:

CREATE FUNCTION getWorkingDays (
    in_start_date IN DATE, 
    in_end_date IN DATE 
) RETURN NUMBER 
IS 
    p_start_date DATE; 
    p_end_date  DATE; 
    p_working_days NUMBER; 
    p_holiday_days NUMBER; 
BEGIN 
    IF in_start_date IS NULL OR in_end_date IS NULL THEN 
    RETURN NUll; 
    END IF; 

    p_start_date := TRUNC(LEAST(in_start_date, in_end_date)); 
    p_end_date := TRUNC(GREATEST(in_start_date, in_end_date)); 

    -- 5/7 * (Number of weekdays between monday of the week containing the start date 
    --   and monday of the week containing the end date) 
    -- + LEAST(day of week for end date, 5) 
    -- - LEAST(day of week for start date, 5) 
    p_working_days := (TRUNC(p_end_date, 'IW') - TRUNC(p_start_date, 'IW')) * 5/7 
        + LEAST(p_end_date - TRUNC(p_end_date, 'IW') + 1, 5) 
        - LEAST(p_start_date - TRUNC(p_start_date, 'IW') + 1, 5); 

    SELECT COUNT(DISTINCT TRUNC(HOLIDAY_DATE)) 
    INTO p_holiday_days 
    FROM ATL_JOB_HOLIDAY jh 
    JOIN ATL_MASTER_JOB mj 
    ON  MJ.MASTER_JOB_ID = JH.MASTER_JOB_ID 
    WHERE TRUNC(HOLIDAY_DATE) BETWEEN p_start_date AND p_end_date; 

    RETURN p_working_days - p_holiday_days; 
END; 
/

(注:HOLIDAY_DATEin_start_datein_end_dateTRUNC進行比對之前進行初始化,所有的時間組件被有效忽略。)

+0

這隻能算一整天 - 處理部分日子,請參閱[本答案](https://stackoverflow.com/a/44407013/1509264)中此函數的修訂版。 – MT0

相關問題