Oracle function 求两个日期之间的工作日

上周帮同事写了一个求两个日期之间的工作日的函数,此处留个笔记。
-------------------------------

限制条件:

1.需要一张节假日登记表

这里写图片描述

2.传入参数第一个要比第二个日期小

CREATE OR REPLACE FUNCTION GET_WORK_DAYS(STARTDAY IN VARCHAR2,
                                         ENDDAY IN VARCHAR2)
  RETURN INTEGER AS SQL_QUERY VARCHAR2(4000);
TMP_QUERY VARCHAR2(4000);
DAY_QUERY VARCHAR2(4000);

OUT_NUM INTEGER;
Z_NUM INTEGER; --总天数
TMP_NUM INTEGER;
DAY_NUM INTEGER; --判断是周几

I INTEGER;

BEGIN
  --总共天数
  DAY_QUERY := ' SELECT abs(to_date(''' || ENDDAY ||
               ''',''yyyy-mm-dd'') - to_date(''' || STARTDAY ||
               ''',''yyyy-mm-dd'')) FROM dual ';
  EXECUTE IMMEDIATE DAY_QUERY
    INTO Z_NUM;
  --输出
  --DBMS_OUTPUT.PUT_LINE(Z_NUM);
  OUT_NUM := Z_NUM+1;
  I       := 0;
  LOOP

    /*
            先判断是周几
            如果是工作日去除休息日
            如果是休息日去除工作日
    */
    IF I > Z_NUM THEN
      EXIT;
    END IF;

    SQL_QUERY := 'SELECT  to_char(to_date(''' || STARTDAY ||
                 ''', ''yyyy-mm-dd'') + ' || I ||
                 ',''d'') FROM dual';
    EXECUTE IMMEDIATE SQL_QUERY
      INTO DAY_NUM;
   -- DBMS_OUTPUT.PUT_LINE(DAY_NUM);

    TMP_QUERY := 'SELECT COUNT(1) FROM SYSTEM_FESTIVAL sf WHERE sf.sfe_type =''休息日'' AND to_char(sf.sfe_date,''yyyy-mm-dd'') = (SELECT to_char(to_date(''' ||
                 STARTDAY || ''', ''yyyy-mm-dd'') + ' || I ||
                 ',''yyyy-mm-dd'') FROM dual)';
    DAY_QUERY := 'SELECT COUNT(1) FROM SYSTEM_FESTIVAL sf WHERE sf.sfe_type =''工作日'' AND to_char(sf.sfe_date,''yyyy-mm-dd'') = (SELECT to_char(to_date(''' ||
                 STARTDAY || ''', ''yyyy-mm-dd'') + ' || I ||
                 ',''yyyy-mm-dd'') FROM dual)';
    --周一
    IF DAY_NUM = 2 THEN
      EXECUTE IMMEDIATE TMP_QUERY
        INTO TMP_NUM;
      IF TMP_NUM > 0 THEN
        OUT_NUM := OUT_NUM - 1;
      END IF;
    END IF;
    --周二
    IF DAY_NUM = 3 THEN
      EXECUTE IMMEDIATE TMP_QUERY
        INTO TMP_NUM;
      IF TMP_NUM > 0 THEN
        OUT_NUM := OUT_NUM - 1;
      END IF;
    END IF;
    --周三
    IF DAY_NUM = 4 THEN
      EXECUTE IMMEDIATE TMP_QUERY
        INTO TMP_NUM;
      IF TMP_NUM > 0 THEN
        OUT_NUM := OUT_NUM - 1;
      END IF;
    END IF;
    --周四
    IF DAY_NUM = 5 THEN
      EXECUTE IMMEDIATE TMP_QUERY
        INTO TMP_NUM;
      IF TMP_NUM > 0 THEN
        OUT_NUM := OUT_NUM - 1;
      END IF;
    END IF;
    --周五
    IF DAY_NUM = 6 THEN
      EXECUTE IMMEDIATE TMP_QUERY
        INTO TMP_NUM;
      IF TMP_NUM > 0 THEN
        OUT_NUM := OUT_NUM - 1;
      END IF;
    END IF;

    --周六
    IF DAY_NUM = 7 THEN

      EXECUTE IMMEDIATE DAY_QUERY
        INTO DAY_NUM;
      IF DAY_NUM = 0 THEN
        OUT_NUM := OUT_NUM - 1;
      END IF;
    END IF;
    --周日
    IF DAY_NUM = 1 THEN
      EXECUTE IMMEDIATE DAY_QUERY
        INTO DAY_NUM;
      IF DAY_NUM = 0 THEN
        OUT_NUM := OUT_NUM - 1;
      END IF;
    END IF;
    I         := I + 1;
  END LOOP;
 -- DBMS_OUTPUT.PUT_LINE(OUT_NUM);
  RETURN OUT_NUM;
END GET_WORK_DAYS;

如果有什么需要改进的地方大家可以留言指正,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java小技巧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值