为什么这个SQL查询有效:
SELECT NEXT_DAY(SYSDATE, 7)
FROM DUAL;
NEXT_DAY(SYSDATE,7) ------------------- 01-APR-17 1 row selected.
...但这个匿名的PL / SQL块不起作用?
DECLARE
dteExpires DATE;
BEGIN
dteExpires := NEXT_DAY(SYSDATE, 7);
END;
Error at line 1 ORA-01846: not a valid day of the week ORA-06512: at line 4
我不想将第二个参数硬编码为前一天的英文名称。 NEXT_DAY(SYSDATE, 'SATURDAY')
或NEXT_DAY(SYSDATE, 'SUNDAY')
等。
目前,我将使用以下方法,但我真的想知道为什么NEXT_DAY()
在PL / SQL中的行为与在SQL中的行为不同。
DECLARE
dteExpires DATE;
BEGIN
-- 2017-01-01 = SUNDAY
dteExpires := NEXT_DAY(SYSDATE, TO_CHAR(TO_DATE('2017-01-01', 'YYYY-MM-DD'), 'DAY'));
END;
这是我的DEV环境:
SELECT *
FROM v$version;
BANNER -------------------------------------------------------------------------------- Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production PL/SQL Release 12.1.0.2.0 - Production CORE 12.1.0.2.0 Production TNS for 64-bit Windows: Version 12.1.0.2.0 - Production NLSRTL Version 12.1.0.2.0 - Production 5 rows selected.
答案 0 :(得分:3)
如果您查看NEXT_DAY的SQL版本的文档,您会发现传入一个代表星期几的数字是没有记录的。无论出于何种原因,它都可以工作,但是如果您依赖它工作,那么您将冒险将来Oracle将更改实现以符合此函数的规定。 (风险很小,因为甲骨文并不疯狂。)
https://docs.oracle.com/database/121/SQLRF/functions118.htm#SQLRF00672
PL / SQL实现仅适用于记录的规范 - 它不接受数字输入来表示一周中的某一天。
我想这是一个间接的答案。我相信你问的是错误的问题。问题不应该是“为什么这不适用于PL / SQL”;相反,给定文档,问题应该是“为什么它在Oracle SQL中有效”。只有Oracle可以回答这个问题。
您可能会发现OTN上的这个讨论非常有用:https://community.oracle.com/thread/4023654
答案 1 :(得分:0)
我认为让函数NEXT_DAY
独立于当前会话NLS_DATE_LANGUAGE
的唯一方法是解决ISO周,其中第一天的星期一是星期一:
SELECT NEXT_DAY(SYSDATE, TO_CHAR(TRUNC(SYSDATE, 'IW')+5, 'Day'))
from dual;
TRUNC(SYSDATE, 'IW')+5
表示“下周六”