SAP HANA计算视图,带SQL脚本的计算列



我已经创建了一个这样的简历"前成员";在这个博客上https://blogs.sap.com/2017/05/18/factory-calendar-transpose-in-sap-hana-studio-step-by-step/

它就像一个符咒!

我的下一个要求是对每条记录采用DATE_SAP,并确定会计月末;是的,我知道这个值在30天内是相同的。

我有一个功能可以工作,并给我会计月结束日期,但我似乎无法确定如何使用我创建的HANA CV视图。

非常感谢!

这是的功能

CREATE FUNCTION "MY_SCHEMA"."FN_DTACCTMONTHEND"
(
-- Add the parameters for the function here
dtexp date
)
RETURNS dtwkend date
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER AS
BEGIN
-- Declare the return variable here
DECLARE dttemp date;
declare cnt int;
declare c_dtwkend date;

Select ADD_DAYS(to_date('19000107', 'YYYYMMDD'),(FLOOR((days_between(to_date('19000107', 'YYYYMMDD'),:dtexp) / 7)) * 7) + 7) into c_dtwkend from dummy;
cnt := 0;
while :cnt < 6 DO

dttemp := add_days(:c_dtwkend,7);
if MONTHNAME(:dttemp) = MONTHNAME(:c_dtwkend) then
c_dtwkend := dttemp;
else
dtwkend := to_date(c_dtwkend);
return;
end if;         
cnt := :cnt + 1;
end while;
-- Return the result of the function
dtwkend := to_date(c_dtwkend);
return;
END;

这是表格功能:

CREATE FUNCTION "SCHEMA_NAME"."SCHEMA_NAME::FN_DTACCTMONTHEND_TEST" (DATE_SAP date ) 
RETURNS TABLE (DTWKEND date)
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER AS
BEGIN
DECLARE dttemp date;
DECLARE cnt int;
DECLARE c_dtwkend date;
DECLARE dtwkend date;

Select ADD_DAYS(to_date('19000107', 'YYYYMMDD'),(FLOOR((days_between(to_date('19000107', 'YYYYMMDD'),:DATE_SAP) / 7)) * 7) + 7) into c_dtwkend
from dummy;
cnt := 0;
while :cnt < 6 DO

dttemp := add_days(:c_dtwkend,7);
if MONTHNAME(:dttemp) = MONTHNAME(:c_dtwkend) then
c_dtwkend := dttemp;
else
dtwkend := to_date(c_dtwkend);
return;
end if;         
cnt := :cnt + 1;
end while;
-- Return the result of the function
dtwkend :=  to_date(c_dtwkend);
RETURN
SELECT dtwkend from dummy;

END;

收到的错误为SAP DBTech JDBC:[2]:一般错误:应为表函数定义带有表达式的RETURN语句

好的,根据注释,要求找到给定月份的最后一个星期日

虽然OP认为计算这一点需要一个循环,并且LAST_DAY函数在这里没有用处,但事实恰恰相反。

借助LAST_DAYWEEKDAY函数可以很容易地计算出一个月的最后一个星期日:

SELECT 
current_date
, LAST_DAY(current_date)
, WEEKDAY (LAST_DAY(current_date)) AS weekday_of_last_day
--
, ADD_DAYS (LAST_DAY(current_date)
,  -( (WEEKDAY(LAST_DAY(current_date)) + 1)           -- how many days back to the last Sunday?
* sign (6 - weekday(last_day(current_date)))    -- set to 0 if the day is a SUNDAY already as THIS is the last Sunday
)
)    AS last_sunday_of_month
FROM 
dummy;

CURRENT_DATE|LAST_DAY(CURRENT_DATE)|WEEKDAY_OF_LAST_DAY|LAST_SUNDAY_OF_MONTH|
------------|----------------------|-------------------|--------------------|
2020-11-01|            2020-11-30|                  0|          2020-11-29|

注意:所选列CURRENT_DATELAST_DAY(current_date)WEEKDAY_OF_LAST_DAY仅用于演示。它们不是列表达式LAST_SUNDAY_OF_MONTH工作所必需的。


在这个例子中,我使用CURRENT_DATE,但可以插入任何日期-计算过程相同。

首先,计算锚月份的LAST_DAYWEEKDAYWEEKDAY产生一个介于0和6之间的数字,表示从星期一开始的工作日,即星期日=6。

如果当前工作日已经是6(=周日(,则不需要减去任何天数即可到达该月的最后一个周日。这是通过将偏移量乘以6(周日的工作日编号(与当前日期的工作日之间的差的SIGN来实现的。如果该差值为正(即在1和6之间(,则偏移量乘以1,如果差值为零,则偏移值乘以0。

这意味着仅CCD_;回到上周日";当当前日期还不是星期日时。

就是这样:不需要循环,也不需要SQLScript代码。此SQL表达式可以在纯SQL或计算视图中使用。

RETURN是为表函数保留的。请改为对while循环使用BREAK。请在下面找到一个例子。

DROP FUNCTION "SCHEMA"."FN_DTACCTMONTHEND_TEST";
CREATE FUNCTION "SCHEMA"."FN_DTACCTMONTHEND_TEST" (DATE_SAP date ) 
RETURNS TABLE (DTWKEND date)
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER AS
BEGIN
DECLARE dttemp date;
DECLARE cnt int := 0;
DECLARE c_dtwkend date;
DECLARE dtwkend date := ADD_DAYS(to_date('19000107', 'YYYYMMDD'),(FLOOR((days_between(to_date('19000107', 'YYYYMMDD'),:DATE_SAP) / 7)) * 7) + 7);

while :cnt < 6 DO

dttemp := add_days(:c_dtwkend,7);
if 
MONTHNAME(:dttemp) = MONTHNAME(:c_dtwkend) 
then
c_dtwkend := dttemp;
else
dtwkend := to_date(c_dtwkend);
BREAK;
end if;         

cnt := :cnt + 1;

end while;

-- Return the result of the function
RETURN
SELECT 
to_date(c_dtwkend) AS DTWKEND
FROM
dummy;

END;

最新更新