Oracle:如何检查系统日期是否不在工作时间

Oracle: how to check if system date not in working hours

如何在 oracle sql 中检查系统日期是否在周五下午 5 点和周一早上 8 点之间。我想实现一个触发器以在 table.

上添加更新限制

找到了可行的解决方案。它可能对某人有帮助。

IF to_char(sysdate, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') IN ('SAT','SUN') 
        THEN
            raise_application_error(-20000, 'message...');
        
    ELSIF to_char(sysdate, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') IN ('FRI') AND to_number(to_char(sysdate, 'hh24MIss')) > 170000
        THEN
            raise_application_error(-20000, 'message...');
            
    ELSIF to_char(sysdate, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') IN ('MON') AND to_number(to_char(sysdate, 'hh24MIss')) < 80000
        THEN
            raise_application_error(-20000, 'message...');
    END IF;

我们可以使用以下查询来查明我们是否在星期一早上 7 点 : 107 和星期五早上 17 点: 517 之间。

select 
  case 
    when to_char(sysdate, 'DHH24',
 'NLS_DATE_LANGUAGE=ENGLISH') 
    between 107 and 517 then 'week'
    else 'weekend' end "rate"
from dual;

您可以独立于 NLS 设置,通过比较当前日期和当前 ISO 周的开始时间(总是在星期一午夜):

IF SYSDATE - TRUNC(SYSDATE, 'IW') < 8/24
THEN
  RAISE_APPLICATION_ERROR(-20000, 'Before 08:00 Monday');
ELSIF SYSDATE - TRUNC(SYSDATE, 'IW') > 4 + 17/24
THEN
  RAISE_APPLICATION_ERROR(-20000, 'After 17:00 Friday');
END IF;

或者,使用 INTERVAL 文字:

IF SYSDATE < TRUNC(SYSDATE, 'IW') + INTERVAL '8' HOUR
THEN
  RAISE_APPLICATION_ERROR(-20000, 'Before 08:00 Monday');
ELSIF SYSDATE > TRUNC(SYSDATE, 'IW') + INTERVAL '4 17:00:00' DAY TO SECOND
THEN
  RAISE_APPLICATION_ERROR(-20000, 'After 17:00 Friday');
END IF;

或者,作为与一天中的时间相对应的界限的单一检查,则:

IF (SYSDATE - TRUNC(SYSDATE, 'IW')) DAY TO SECOND
      NOT BETWEEN INTERVAL '0 08:00:00' DAY TO SECOND
              AND INTERVAL '4 17:00:00' DAY TO SECOND
THEN
  RAISE_APPLICATION_ERROR(-20000, 'Outside working hours.');
END IF;

db<>fiddle here

您可以在一次 closed-form 计算中完成。如果 time-of-week 介于星期一 08:00 和星期五 17:00 之间,则表示您“在工作时间内”(根据您的定义)。这与“sysdate”相同 - 星期一 00:00 和星期五 09:00 之间有 8 个小时。这也意味着当且仅当“sysdate - 8 小时”的 time-of-week 严格大于星期五 09:00.

时,你才“在周末”

所有这些都可以使用日期和间隔算法轻松表达:

if ((sysdate - interval '8' hour) - trunc(sysdate - interval '8' hour, 'iw')
   ) day to second > interval '4 9:00:00' day to second
then .......
end if;