我在 SQL Developer 中开发了这个查询:
WITH FUNCTION AMS_SUBTRACT_WORKDAY(VDATE IN DATE, VDAYS IN NUMBER)
RETURN DATE
IS
VENDD DATE;
VDYWR NUMBER := 5;
VDYCL NUMBER := 7;
VDAYD NUMBER;
VDAY2 NUMBER := VDAYS;
VWEKS NUMBER;
BEGIN
SELECT TO_NUMBER(VDATE - TRUNC(VDATE, 'IW')) INTO VDAYD FROM DUAL;
IF VDAYD > VDAY2 THEN
VENDD := VDATE - VDAY2;
ELSE
VDAY2 := VDAY2 - VDAYD;
VENDD := TRUNC(VDATE, 'IW');
VENDD := VENDD - (TRUNC(VDAY2 / 5) * 7) - 2;
VDAY2 := VDAY2 - (TRUNC(VDAY2 / 5) * 5);
VENDD := VENDD - VDAY2;
END IF;
RETURN VENDD;
END AMS_SUBTRACT_WORKDAY;
SELECT AMS_SUBTRACT_WORKDAY(DATE '2024-09-28', 5) RES FROM DUAL;
给出以下结果:
问题是,如果我通过 SQLPlus 或 SQLcl 运行它,WITH 子句似乎不会被识别为 SELECT 的一部分。因此它停止处理。
非常感谢任何帮助。
在 SQL*Plus 和 SQLcl 中,PL/SQL 代码必须以正斜杠终止才能运行*。例如:
SQL> with function test1 return number is begin return 1; end;
2 select test1 from dual;
3 /
TEST1
----------
1
SQL>
* 这种简单化的总结在 Oracle 的最新版本中并不真实,因为 SQL 和 PL/SQL 正在逐渐合并。上面的代码最准确地仍然称为 SQL 语句,尽管它内部显然使用了 PL/SQL。当两种语言相遇时,语句解析可能会变得很奇怪,例如在对象类型和触发器中。
一般来说,如果 SQL*Plus 读取前几个标记(?)并确定代码将包含不结束语句的分号,它将在一行中单独查找正斜杠。其他 IDE 的工作方式会有所不同,有些 IDE 根本无法正确解析 PL/SQL WITH 函数。当实际执行语句时,例如,如果您在
EXECUTE IMMEDIATE
字符串中动态运行它,则不应包含正斜杠。 (类似于动态执行的 SQL 语句不应该有终止分号的方式。)