具有SQL脚本的计算列的SAP HANA计算视图

问题描述

我已经在此Blog上创建了简历,就像这个“前会员”一样 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',: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',: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,但是可以插入任何日期-计算原理相同。

首先,计算锚定月份WEEKDAY中的LAST_DAYWEEKDAY产生一个介于0和6之间的数字,代表从DAY开始的工作日,即SUNDAY = 6。

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

这意味着,ADD_DAYS仅在当前日期还不是星期日时才“返回到最后一个星期日”。

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

,

RETURN保留用于表功能。使用BREAK代替while循环。 请在下面找到一个示例。

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',: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;

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...