以日期为准,往前推X天工作日的日期

--*******************************************************************************
  --功能说明:  以日期为准,往前推X天工作日的日期
           --取ntl_ot_work_calendar表来确定该日期是否在表中存在:
           --如果该记录在表中存在,判断是否为工作日;
           --如果该记录在表中不存在,则默认为工作日
  --参数说明:假设传入2012-09-10号,2天,得到日期为2012-09-06(7号,8号为休息日)
  --调用函数:
  --修改记录:
  --******************************************************************************/
  FUNCTION FUN_GET_DATE_BY_WORK_DAY(P_CHANGE_DATE IN DATE,
                                P_WORK_DAYS   IN NUMBER)
    RETURN NTL_OT_WORK_CALENDAR.DATE_CALENDAR%TYPE IS
    V_CHANGE_DATE         NTL_OT_WORK_CALENDAR.DATE_CALENDAR%TYPE;
    FLAG_WORK_DAY         BOOLEAN := TRUE;
    V_FIND_RECORD         NUMBER(2) := 0;
    V_FIND_WORKDAY_RECORD NUMBER(2) := 0;
    V_DAYS                NUMBER(2) := -1;
    V_LOGIC_DATE          NTL_OT_WORK_CALENDAR.DATE_CALENDAR%TYPE;
  BEGIN
    IF (P_CHANGE_DATE IS NOT NULL) THEN
      V_LOGIC_DATE := P_CHANGE_DATE;
    ELSE
      V_LOGIC_DATE := TRUNC(SYSDATE);
    END IF;
    WHILE FLAG_WORK_DAY LOOP
      select COUNT(1)
        INTO V_FIND_RECORD
        from NTL_OT_WORK_CALENDAR T
       WHERE TRUNC(T.DATE_CALENDAR) = TRUNC(V_LOGIC_DATE);
      --说明该日期在日历设置表中存在
      IF (V_FIND_RECORD <> 0) THEN
        select COUNT(1)
          INTO V_FIND_WORKDAY_RECORD
          from NTL_OT_WORK_CALENDAR T
         WHERE TRUNC(T.DATE_CALENDAR) = TRUNC(V_LOGIC_DATE)
           AND T.IS_WORKDAY = '1';
        --说明该日期为工作日
        IF (V_FIND_WORKDAY_RECORD <> 0) THEN
          V_CHANGE_DATE := TRUNC(V_LOGIC_DATE);
          V_DAYS        := V_DAYS + 1;
        END IF;
      ELSE
        V_CHANGE_DATE := TRUNC(V_LOGIC_DATE);
        V_DAYS        := V_DAYS + 1;
      END IF;
      IF (V_DAYS = P_WORK_DAYS) THEN
        FLAG_WORK_DAY := FALSE;
      END IF;
      V_LOGIC_DATE := V_LOGIC_DATE - 1;
    END LOOP;
    RETURN V_CHANGE_DATE;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END FUN_GET_DATE_BY_WORK_DAY;

猜你喜欢

转载自opportunity.iteye.com/blog/1735996