Почему NEXT_DAY работает иначе в PL/SQL чем в SQL? ORA-01846: not a valid day of the week
Этот SQL запрос работает:
SELECT NEXT_DAY (sysdate, 7) "NEXT DAY" FROM DUAL;
NEXT DAY
-------------------
2021-08-15 00:31:12
Но в PL/SQL эта же функция не работает:
declare
nextday date := NEXT_DAY (sysdate, 7);
begin null;
end;
/
ORA-01846: not a valid day of the week
Не хотелось бы жестко кодировать дни недели во втором параметре на английском, например:
NEXT_DAY(SYSDATE, 'SATURDAY')
--или
NEXT_DAY(SYSDATE, 'SUNDAY')
Пока использую следующее решение:
dteExpires DATE := NEXT_DAY (SYSDATE, TO_CHAR(TO_DATE('2021-08-15', 'YYYY-MM-DD'), 'DAY'));
Хотелось бы узнать, почему NEXT_DAY() ведет себя иначе в PL/SQL, чем в SQL?
Свободный перевод вопроса NEXT_DAY function works differently in SQL vs. PL/SQL? от участника @wweicker
Ответы (2 шт):
Если посмотрeть документацию к SQL функции NEXT_DAY, то можно заметить, что передача числа для представления дня недели не документирована. По какой-то причине она работает, но если положиться на это, то есть риск, что в будущем Oracle изменит реализацию, чтобы она соответствовала спецификации этой функции (риск невелик, но всё таки).
Реализация PL/SQL работает только с документированной спецификацией - она не принимает числовой параметр для представления дня недели.
Учитывая документацию, вопрос лучше поставить так: Почему это работает в SQL?.
Только разработчики Oracle могут ответить на этот вопрос.
Возможно это обсуждение на OTN будет полезно, или это тоже.
Считаю, что единственный способ сделать функцию NEXT_DAY независимой от текущих NLS параметров сессии БД, это обходной путь с ISO-неделей, где первый день недели всегда понедельник. То есть, добавив 1 - будет вторник, 2 - среда и т.д.:
declare
nextday date := next_day (sysdate, to_char (trunc (sysdate, 'IW')+4, 'DAY'));
begin
dbms_output.put_line ('next day='||nextday);
end;
/
next day=2021-08-13 01:25:54
Свободный перевод ответа от участника @Wernfried Domscheit