SQL проверка день недели - PullRequest
       4

SQL проверка день недели

0 голосов
/ 09 сентября 2018

Как проверить, выходной ли это в SQL? Я знаю, что могу конвертировать sysdate в число с помощью этого

 SQL> select to_char(sysdate, 'd') from dual;

 TO_CHAR(SYSDATE,'D')

Но я не совсем уверен, как проверить, сегодня 6 или 7.

Ответы [ 4 ]

0 голосов
/ 10 сентября 2018

Не используйте TO_CHAR с моделью формата D для этого, так как это зависит от параметра сеанса NLS_TERRITORY.

Например, когда SYSDATE = 2018-09-10 (понедельник):

ALTER SESSION SET NLS_TERRITORY = 'France';
SELECT TO_CHAR( SYSDATE, 'D' ) FROM DUAL;

Вывод 1, но тот же запрос на другой территории:

ALTER SESSION SET NLS_TERRITORY = 'America';
SELECT TO_CHAR( SYSDATE, 'D' ) FROM DUAL;

Выходы 2.

Вместо этого вы можете использовать TRUNC и модель формата IW:

SELECT TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ) FROM DUAL

Вывод 0 для понедельника (и 1 для вторника ... 6 для воскресенья) и не зависит от настройки NLS_TERRITORY.

Таким образом, вы можете отфильтровать это, чтобы дать выходные дни как:

SELECT *
FROM   DUAL
WHERE  TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ) IN ( 5, 6 )

или

SELECT *
FROM   DUAL
WHERE  SYSDATE - TRUNC( SYSDATE, 'IW' ) >= 5

Если вы хотите, чтобы 1-индексированные дни соответствовали ожидаемому результату от TO_CHAR (а не 0-индексировались), просто добавьте 1 к значению.

0 голосов
/ 10 сентября 2018

А вот логика в многократно используемой функции, но перевернулся, чтобы спросить: "Это будний день?" (не выходные). Вы можете добавить параметр для начального дня в рабочие дни (2 по умолчанию в Oracle; воскресенье - день # 1).

CREATE OR REPLACE FUNCTION is_weekday (date_in IN DATE) 
   RETURN BOOLEAN 
IS 
BEGIN 
   RETURN TO_CHAR (date_in, 'D') BETWEEN 2 AND 6; 
END; 
/

DECLARE 
   l_date   DATE := DATE '2018-09-10'; 
BEGIN 
   DBMS_OUTPUT.put_line ('If your weekend is Saturday and Sunday....'); 

   FOR indx IN 1 .. 7 
   LOOP 
      DBMS_OUTPUT.put_line ( 
            TO_CHAR (l_date, 'FMDay, Month DD YYYY') 
         || ' is ' 
         || CASE WHEN NOT is_weekday (l_date) THEN 'not ' END 
         || 'a weekday'); 
      l_date := l_date + 1; 
   END LOOP; 
END; 
/

Попробуйте в LiveSQL: https://livesql.oracle.com/apex/livesql/file/content_G8NQSY6NP48NPJX96RLQ51SUE.html

0 голосов
/ 10 сентября 2018

Я бы избежал неоднозначного формата 'D', так как он варьируется между территориями (неделя начинается после выходных, в которых я живу), и использую

if to_char(sysdate,'fmDY','nls_date_language=English') like 'S%'
then

Что касается формата 'D', к сожалению, to_char не позволяет указывать nls_territory inline, поэтому без явной команды alter session он будет полагаться на настройки сеанса во время выполнения. Из-за этого я видел производственные ошибки, когда тот же код работал в Лондоне, но не работал в Нью-Йорке.

0 голосов
/ 09 сентября 2018

sysdate - псевдостолбец. Вам не нужно запрашивать его, вы можете оценить его напрямую:

IF TO_CHAR(SYSDATE, 'D') IN ('6', '7') THEN
    -- Do something
END IF;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...