NEXT_DAY函数在SQL与PL/SQL中的工作方式不同?

wwe*_*ker 5 sql oracle plsql date oracle12c

为什么这个SQL查询有效:

SELECT NEXT_DAY(SYSDATE, 7)
FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
NEXT_DAY(SYSDATE,7)
-------------------
01-APR-17          
1 row selected.
Run Code Online (Sandbox Code Playgroud)

...但是这个匿名的PL/SQL块不起作用?

DECLARE
  dteExpires DATE;
BEGIN
  dteExpires := NEXT_DAY(SYSDATE, 7);
END;
Run Code Online (Sandbox Code Playgroud)
Error at line 1
ORA-01846: not a valid day of the week
ORA-06512: at line 4
Run Code Online (Sandbox Code Playgroud)

我不想将第二个参数硬编码为前一天的英文名称.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;
Run Code Online (Sandbox Code Playgroud)

这是我的DEV环境:

SELECT *
FROM v$version;
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)

小智 4

如果你检查 NEXT_DAY 的 SQL 版本的文档,你会发现传递一个数字来代表一周中的某一天是没有文档记录的。无论出于何种原因,它都可以工作,但如果您依赖它工作,那么您将面临 Oracle 将来将更改实现以符合该功能规定的规范的风险。(风险很小,因为 Oracle 并不疯狂。)

https://docs.oracle.com/database/121/SQLRF/functions118.htm#SQLRF00672

PL/SQL 实现仅适用于记录的规范 - 它不接受代表一周中的某一天的数字输入。

我想这是一个间接的答案。我相信你问错了问题。问题不应该是“为什么这在 PL/SQL 中不起作用”;而是“为什么这在 PL/SQL 中不起作用”。相反,鉴于文档,问题应该是“为什么它在 Oracle SQL 中工作”。只有 Oracle 可以回答这个问题。

您可能会发现 OTN 上的讨论很有用:https ://community.oracle.com/thread/4023654

也许这也是: https: //community.oracle.com/ideas/17257?tab=comment