PL / SQL新手:SELECT和SYSDATE的函数

时间:2014-01-28 19:33:15

标签: sql oracle plsql

我是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;

这是我试图将上述内容变成一个函数(因为你可以看到它没那么热)...

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;

我做错了什么?

1 个答案:

答案 0 :(得分:6)

你真的想在那里返回三个值。我建议将其分解为单独的函数,但将“今天的日期”保留为对sysdate的调用。

您不需要发出SELECT查询来填充变量,在这种情况下,您只需返回一个表达式。

CREATE OR REPLACE FUNCTION first_tuesday
  RETURN DATE
AS
BEGIN
  RETURN NEXT_DAY(trunc(SYSDATE, 'MONTH')-1, 'Tuesday')
END;
/

需要注意的是,在执行SQL语句时,SYSDATE始终具有相同的值,但PL / SQL中的情况并非如此。因此,当在从SQL语句调用的PL / SQL中计算sysdate时,您可以在每个上下文中获得不同的值。所以如果你打电话:

select sysdate col1,
       some_function col2
from dual;

...在执行冗长的过程中,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;
/

那么你可能......

Select ...
From   invoices
Where  invoice_date < first_tuesday(sysdate)

这是一个简单的例子,只是为了演示原理,它实际上只对从SQL调用的函数很重要。

老实说,在你的情况下,大多数从业者可能会跳过这个功能而只是:

Select ...
From   invoices
Where  invoice_date < NEXT_DAY(trunc(sysdate, 'MONTH')-1, 'Tuesday')

编辑:顺便说一句,您可能想要使用:

NEXT_DAY (LAST_DAY(SYSDATE),'TUESDAY')

......不......

NEXT_DAY (LAST_DAY(SYSDATE)+1,'TUESDAY')