我是SQL的新手,希望能帮助我们将其变成一个函数:
SELECT
SYSDATE "Today's Date",
NEXT_DAY(trunc(SYSDATE, 'MONTH')-1, 'Tuesday')"First Tuesday this Month",
NEXT_DAY (LAST_DAY(SYSDATE)+1,'TUESDAY') "First Tuesday of Next Month"
FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
这是我尝试将上述内容转换为函数(因为你可以看到它没有那么热)...
CREATE OR REPLACE FUNCTION first_tuesday
RETURN DATE
AS
date1 DATE;
date2 DATE;
date3 DATE;
BEGIN
date1 := SELECT SYSDATE;
date2 := SELECT NEXT_DAY(trunc(SYSDATE, 'MONTH')-1, 'Tuesday');
date3 := SELECT NEXT_DAY (LAST_DAY(SYSDATE)+1,'TUESDAY');
RETURN 'todays date:' || date1,
'first tuesday this month:' || date2,
'first tuesday next month:' || date3;
END;
/
SELECT first_tuesday FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
你真的想在那里返回三个值.我建议将其分解为单独的函数,但将"今天的日期"保留为对sysdate的调用.
您不需要发出SELECT查询来填充变量,在这种情况下,您只需返回一个表达式.
CREATE OR REPLACE FUNCTION first_tuesday
RETURN DATE
AS
BEGIN
RETURN NEXT_DAY(trunc(SYSDATE, 'MONTH')-1, 'Tuesday')
END;
/
Run Code Online (Sandbox Code Playgroud)
这里需要注意的是,在执行SQL语句时,SYSDATE始终具有相同的值,但PL/SQL中的情况并非如此.因此,当在从SQL语句调用的PL/SQL中计算sysdate时,您可以在每个上下文中获得不同的值.所以如果你打电话:
select sysdate col1,
some_function col2
from dual;
Run Code Online (Sandbox Code Playgroud)
...在执行冗长的过程中,some_function会计算sysdate,它可能会使用与父SQL语句略有不同(稍后)的值.
避免这种情况的方法是将sysdate传递给函数:
CREATE OR REPLACE FUNCTION first_tuesday (sysdate_in date)
RETURN DATE
AS
BEGIN
RETURN NEXT_DAY(trunc(sysdate_in, 'MONTH')-1, 'Tuesday')
END;
/
Run Code Online (Sandbox Code Playgroud)
那么你可能......
Select ...
From invoices
Where invoice_date < first_tuesday(sysdate)
Run Code Online (Sandbox Code Playgroud)
这是一个简单的例子,只是为了演示原理,它实际上只对从SQL调用的函数很重要.
说实话,在你的情况下,大多数从业者可能会跳过这个功能而且只是:
Select ...
From invoices
Where invoice_date < NEXT_DAY(trunc(sysdate, 'MONTH')-1, 'Tuesday')
Run Code Online (Sandbox Code Playgroud)
编辑:顺便说一句,您可能想要使用:
NEXT_DAY (LAST_DAY(SYSDATE),'TUESDAY')
Run Code Online (Sandbox Code Playgroud)
......不......
NEXT_DAY (LAST_DAY(SYSDATE)+1,'TUESDAY')
Run Code Online (Sandbox Code Playgroud)