0

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

就像是

IS_HOLIDAY(:DATEINPUT)

我需要在没有存储过程的情况下执行此操作。在我的 select 语句中,我想做的是在 where 子句中过滤掉基于 holday 的数据。

请帮忙。

4

3 回答 3

6

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

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

于 2012-07-05T17:43:24.487 回答
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;
于 2013-04-18T17:52:11.787 回答
0

您不能将美国假期存储在不同的表中,然后加入吗?

我确信那里有免费的公共数据可以提供你需要的东西。例如,该站点显示了 2012 年至 2020 年的所有美国银行假日:https ://gist.github.com/shivaas/4758439

于 2014-03-13T23:08:49.447 回答