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

时间:2017-03-29 21:43:36

标签: sql oracle date plsql oracle12c

为什么这个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.

2 个答案:

答案 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

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

答案 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表示“下周六”