Oracleには、日付をパラメーターとして渡すことができるデフォルトの関数があり、それが米国の祝日であるかどうかを返しますか?
何かのようなもの
IS_HOLIDAY(:DATEINPUT)
ストアドプロシージャなしでこれを行う必要があります。selectステートメントで実行したいのは、where句のholdayに基づいてデータをフィルターで除外することです。
助けてください。
いいえ。組み込み関数はありません。米国の祝日だけに切り詰めたとしても、それはまだ確定的ではありません。州によって祝日が異なり、会社によって祝日の認識が異なり、会社によって祝日の扱いが異なります (つまり、土曜日に当たる祝日は、前の金曜日に祝われるか、次の月曜日に祝われるか、またはまったく祝われない場合があります)。現実的には、これは、組織が認識している休日と、それらの休日がいつ祝われるかを示すカスタム テーブルがほぼ確実に必要であることを意味します。
これにストアドプロシージャを使用できないのはなぜですか? もちろん、SQL クエリで有効な休日を単純にリストすることもできますが、それはかなり洗練されていません。休日のテーブルと、日付が休日に該当するかどうかを判断するストアド関数の方がはるかに実用的です。
米国の祝日を別のテーブルに保存してから結合できませんか?
必要なものを提供する無料の公開データが世の中にあると確信しています。たとえば、このサイトでは 2012 年から 2020 年までのすべての米国の祝日が表示されます: https://gist.github.com/shivaas/4758439
これは、私たちが休日かどうかをテストするために書いた関数です。政府の休日またはその他の休日の後の最初の営業日が必要な場合は、2 番目の機能も使用できます。
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;