确定Oracle中的假期

时间:2012-07-05 17:36:34

标签: sql oracle date

Oracle中是否有默认函数允许您将日期作为参数传递,并返回是否为美国假日?

类似

IS_HOLIDAY(:DATEINPUT)

我需要这样做没有存储过程。在我的select语句中,我想要做的是在我的where子句中基于holday过滤掉数据。

请帮忙。

3 个答案:

答案 0 :(得分:5)

没有。没有内置功能。即使你把它缩减到美国假期,这仍然不是确定性的。不同的州有不同的假期,不同的公司承认不同的假期,不同的公司以不同的方式处理假期(即,星期六的假期可能在前一个星期五,随后的星期一或根本不庆祝)。实际上,这意味着您的组织几乎肯定需要一个自定义的假期表,您的组织会认可这些假期以及庆祝这些假期。

为什么不能为此使用存储过程?当然,您可以简单地在SQL查询中列出有效假期,但这样做会相当不优雅 - 一个假期表和一个确定日期是否属于假期的存储函数似乎更实用。

答案 1 :(得分:0)

这是我写的一个函数,用于测试我们是否度假。请注意,如果您需要在政府假期或其他假期后的第一个工作日,那么您也可以使用第二个功能。

create or replace 
FUNCTION IS_HOLIDAY(V_DT DATE) RETURN VARCHAR2 AS
RET VARCHAR2(1);
V_MONTH VARCHAR2(2);
V_DAY VARCHAR2(2);
V_YEAR VARCHAR2(4); 
MLK DATE;
WASHINGTON DATE;
MEMORIAL DATE;
COLUMBUS DATE;
THANKSGIVING DATE;
BEGIN
 RET:='F';
 SELECT TO_CHAR(V_DT,'YYYY') INTO V_YEAR FROM DUAL;
 SELECT TO_CHAR(V_DT,'MM') INTO V_MONTH FROM DUAL;
 SELECT TO_CHAR(V_DT,'dd') INTO V_DAY FROM DUAL;
 SELECT NEXT_DAY(TO_DATE(TO_CHAR(SYSDATE,'YYYY')||'0201','YYYYMMdd')-1,'MON')+14 INTO WASHINGTON FROM DUAL;
 SELECT NEXT_DAY(TO_DATE(TO_CHAR(SYSDATE,'YYYY')||'0101','YYYYMMdd')-1,'MON')+14 INTO MLK FROM DUAL;
 SELECT NEXT_DAY(TO_DATE(TO_CHAR(SYSDATE,'YYYY')||'0201','YYYYMMdd')-1,'MON')+14 INTO WASHINGTON FROM DUAL;
 SELECT NEXT_DAY(LAST_DAY(TO_DATE(TO_CHAR(SYSDATE,'YYYY')||'0501','YYYYMMdd'))-7,'MONDAY')INTO MEMORIAL FROM DUAL;
 SELECT NEXT_DAY(TO_DATE(TO_CHAR(SYSDATE,'YYYY')||'1001','YYYYMMdd')-1,'MON')+7  INTO COLUMBUS FROM DUAL;
 SELECT NEXT_DAY(TO_DATE(TO_CHAR(SYSDATE,'YYYY')||'1101','YYYYMMdd')-1,'THURSDAY')+21 INTO THANKSGIVING FROM DUAL;
 IF(TRUNC(V_DT) = TRUNC(MLK) )THEN RET:='T';
 ELSIF(TRUNC(V_DT)=TRUNC(WASHINGTON))THEN RET :='T';
 ELSIF(TRUNC(V_DT)=TRUNC(MEMORIAL) )THEN RET:='T';
 ELSIF(TRUNC(V_DT)=TRUNC(COLUMBUS)) THEN RET:= 'T';
 ELSIF(TRUNC(V_DT)=TRUNC(THANKSGIVING)) THEN RET:='T';
 ELSIF(V_MONTH ='01' AND V_DAY='01') THEN RET:='T';  --NEW YEARS
 ELSIF(V_MONTH='07' AND V_DAY='04') THEN RET:='T';
 ELSIF(V_MONTH='09' AND V_DAY='02') THEN RET:='T';
 ELSIF(V_MONTH='11' AND V_DAY='11') THEN RET:='T';
 ELSIF(V_MONTH='12' AND V_DAY='25') THEN RET:='T';
 END IF;  
 RETURN RET;

END DIS_IS_HOLIDAY;

下一个功能将在假期的第一个工作日

找到
create or replace 
 FUNCTION first_business_day (v_dt DATE)
   RETURN DATE
 IS
   return_dt   DATE;
  BEGIN
   SELECT CASE
         WHEN (CASE
                  WHEN( TO_CHAR (TRUNC (V_DT, 'MM'), 'DY') IN
                          ('SAT', 'SUN'))
                  THEN
                     NEXT_DAY (TRUNC (v_dt, 'MM'), 'MON')
                  ELSE
                     TRUNC (V_DT, 'MM')
                  END) IS NOT NULL AND DIS_IS_HOLIDAY(V_DT)='T'

         THEN
            CASE
               WHEN TO_CHAR (TRUNC (v_dt, 'MM') + 1, 'DY') IN
                       ('SAT', 'SUN')
               THEN
                  NEXT_DAY (TRUNC (v_dt, 'MM') + 1, 'MON')
               ELSE
                  TRUNC (v_dt, 'MM') + 1
            END
         ELSE
            CASE
               WHEN TO_CHAR (TRUNC (v_dt, 'MM'), 'DY') IN ('SAT', 'SUN')
               THEN
                  NEXT_DAY (TRUNC (v_dt, 'MM'), 'MON')
               ELSE
                  TRUNC (v_dt, 'MM')
            END
      END
   INTO return_dt
   FROM DUAL;

 RETURN return_dt;
END;

答案 2 :(得分:0)

你不能把美国假期存放在另一张桌子上,然后加入吗?

我确信那里有免费的公共数据可以满足您的需求。例如,此网站显示2012年至2020年的所有美国银行假日:https://gist.github.com/shivaas/4758439