创建一个 SQL 函数,如果日期是假日,则返回



我需要创建一个日历,在一行中显示一个月的所有日子。然后,我需要显示同一个月的另一行,但显示当天的第一个字母(M表示星期一,S表示星期日等(,如果是假日,则添加一个字母(C表示民事,R表示宗教(。

输出示例:

Date           Day
gennaio  2022, 1,  2, 3, 4, 5,  6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
gennaio  2022, Sr, D, L, M, M, Gr, V, S, D,  L,  M,  M,  G,  V,  S,  D,  L,  M,  M,  G,  V,  S,  D,  L,  M,  M,  G,  V,  S,  D,  L
febbraio 2022, 1,  2, 3, 4, 5,  6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, <null>, <null>, <null>
febbraio 2022, M,  M, G, V, S,  D, L, M, M,  G,  V,  S,  D,  L,  M,  M,  G,  V,  S,  D,  L,  M,  M,  G,  V,  S,  D,  L, <null>, <null>, <null>

我使用了一张包含所有假期日期的表格,并从中进行了选择,以返回当天是否是假期。

我想知道是否有可能,以及如何创建一个函数,在不需要额外表格的情况下返回日期是否为假日(我在2021年1月1日至2025年12月31日创建了该函数,这意味着更早或更晚会出现错误(

我是意大利人,由于除了复活节之外,所有的假期都是固定的,我想函数只需要计算复活节日期,我就可以插入所有其他假期。

它的想法是通过函数从一个日期间隔(在我的情况下是从2021年1月1日至2025年12月31日(中进行选择,然后将其格式化为具有如上所示的2列以及所有日期和假日。

提前谢谢大家。

您可以根据高斯的复活节算法计算复活节:

CREATE OR REPLACE FUNCTION Easter(yyyy IN INTEGER DEFAULT TO_CHAR(SYSDATE, 'YYYY')) RETURN DATE IS
a INTEGER;
b INTEGER;
c INTEGER;
d INTEGER;
e INTEGER;
f INTEGER;
g INTEGER;
h INTEGER;
i INTEGER;
k INTEGER;
l INTEGER;
m INTEGER;
n INTEGER;
p INTEGER;
EM INTEGER;
ED INTEGER;
BEGIN
a := yyyy MOD 19;
b := TRUNC(yyyy / 100);
c := yyyy MOD 100;
d := TRUNC(b / 4);
e := b MOD 4;
f := TRUNC((b + 8) / 25);
g := TRUNC((b - f + 1) / 3);
h := (19*a + b - d - g + 15) MOD 30;
i := TRUNC(c / 4);
k := c MOD 4;
l := (32 + 2*e + 2*i - h - k) MOD 7;
m := TRUNC((a + 11*h + 22*l) / 451);
n := TRUNC((h + l - 7*m + 114) / 31);
p := (h + l - 7*m + 114) MOD 31;
EM := n;
ed := p + 1;

RETURN TO_DATE(yyyy||'-'||EM||'-'||ed, 'YYYY-MM-DD');
END Easter;

对于其他日子,你必须放一些简单的逻辑,例如

TO_CHAR(inputDate, 'MM-DD') = '12-25'

圣诞节。一些假日被定义为";十一月的第三个星期一";,可能是这个:

TRUNC(inputDate) = NEXT_DAY(TRUNC(inputDate, 'MM')-1, 'MONDAY') + 2 * 7

简化示例:

CREATE OR REPLACE FUNCTION IsHoliday(d IN DATE) RETURN BOOLEAN IS
easter DATE := Easter(TO_CHAR(d, 'YYYY'));
BEGIN
IF TO_CHAR(d, 'Dy', 'NLS_DATE_LANGUAGE = "American"') IN ('Sat','Sun') THEN RETURN TRUE; -- Weekend
IF TRUNC(d) = easter + 1 THEN RETURN TRUE; -- Easter Monday
IF TO_CHAR(d, 'MM-DD') IN ('12-25', '12-26') THEN RETURN TRUE; -- Christmas
IF TO_CHAR(d, 'MM-DD') = '05-01' THEN RETURN TRUE; -- Festa del Lavoro
... some more
RETURN FALSE;
END IsHoliday;

另一种方法是DBMS_SCHEDULER.EVAUATE_CALENDAR_STRING,例如:

DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING(
--Wednesday before November 23th 
'FREQ=DAILY;BYDATE=1122-SPAN:7D;BYDAY=WED', 
NULL, TRUNC(d, 'YYYY')-1, next_run_date);
IF TRUNC(d) = next_run_date THEN RETURN TRUE;

查看更多示例

相关内容

最新更新