简体   繁体   English

ABAP CDS View - 使用类方法

[英]ABAP CDS View - use a class method

I would like to call a method from a class in an existing CDS view to get certain data, which can only be called by this method.我想从现有 CDS 视图中的类中调用一个方法来获取某些数据,这些数据只能由该方法调用。 So I want to call a method from a CDS View.所以我想从 CDS 视图调用一个方法。

What is the easiest way to do this?什么是最简单的方法来做到这一点?

I would be very happy about an example with code.我会对代码示例感到非常高兴。

NOTE: Your abap logic will only be executed when the CDS view is consumed by something that handles annotations ie exposed as an Odata service, but not in transaction SE16N or the preview in Eclipse.注意:您的 abap 逻辑只会在 CDS 视图被处理注释的东西使用时执行,即作为 Odata 服务公开,而不是在事务 SE16N 或 Eclipse 中的预览中。 There two ways actually.其实有两种方式。 First option:第一个选项:

@AbapCatalog.sqlViewName: 'ZV_TEST_ABAP'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'ABAP code in cds'
@OData.publish: true
define view YCDS_WITH_ABAP as select from sflight
{

  //sflight
  key carrid,
  key connid,
  key fldate,
      seatsocc_f,
      @ObjectModel.readOnly: true
      @ObjectModel.virtualElement: true 
      @ObjectModel.virtualElementCalculatedBy: 'ABAP:YCL_CDS_FUNCTION' //ycl_cds_function 
      cast( '' as abap.char(255)) as text
    
}where connid = '0017'

Your abap class:您的 abap 课程:

CLASS ycl_cds_function DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .



  PUBLIC SECTION.
    INTERFACES: if_sadl_exit_calc_element_read.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS ycl_cds_function IMPLEMENTATION.

 METHOD if_sadl_exit_calc_element_read~calculate.

    DATA:
      lt_calculated_data TYPE STANDARD TABLE OF ZV_TEST_ABAP .

    " it_original_data -> data that comes from cds
    " lt_calculated_data -> data that you will manipulate
    MOVE-CORRESPONDING it_original_data TO lt_calculated_data.

    " do your extra logic and append/update your cds view data
    LOOP AT lt_calculated_data ASSIGNING FIELD-SYMBOL(<fs_data>).
        <fs_data>-text = 'hello from abap!'.
    ENDLOOP.

    MOVE-CORRESPONDING lt_calculated_data TO ct_calculated_data.

  ENDMETHOD.

  METHOD if_sadl_exit_calc_element_read~get_calculation_info.

  ENDMETHOD.

ENDCLASS.

View in eclipse:在日食中查看: 在此处输入图片说明 View in odata:在 odata 中查看:

  ...,{
                "__metadata": {
                    "id": "lalala')",
                    "uri": "blablabla')",
                    "type": "YCDS_WITH_ABAP_CDS.YCDS_WITH_ABAPType"
                },
                "carrid": "AA",
                "connid": "0017",
                "fldate": "/Date(1535068800000)/",
                "seatsocc_f": 20,
                "text": "hello from abap!"
   },...

Second option:第二种选择:

The second way is to change your service's DPC class with your custom class, which inherits this standard class and do your custom logic in those redefined methods.第二种方法是使用自定义类更改服务的 DPC 类,该类继承此标准类并在这些重新定义的方法中执行自定义逻辑。 Personally, I would go with the second option.就我个人而言,我会选择第二个选项。 I haven't tried it but I have a feeling that performance would be better.我还没有尝试过,但我觉得性能会更好。 :) :)

在此处输入图片说明

For more info please check: https://blogs.sap.com/2020/05/11/abap-code-exits-in-cds-views/更多信息请查看: https : //blogs.sap.com/2020/05/11/abap-code-exits-in-cds-views/

While @Oguz answer is worth knowing from an OData perspective, there is also a pure CDS solution that works in every component that selects from CDS views, independent on whether they support annotations or not.虽然@Oguz 的回答值得从 OData 的角度了解,但还有一个纯 CDS 解决方案,适用于从 CDS 视图中选择的每个组件,独立于它们是否支持注释。

First, you specify a CDS view as a SELECT FROM <table function> :首先,您将 CDS 视图指定为SELECT FROM <table function>

@AbapCatalog.sqlViewName: 'MYCDSVIEW'
define view MY_CDS_VIEW as select from MY_TABLE_FUNCTION {    
    A,
    B
}

Then you define a table function.然后定义一个表函数。 Table functions are like CDS view, only that their execution logic is implemented in ABAP, not in SQL Script:表函数类似于CDS视图,只是它们的执行逻辑是在ABAP中实现的,而不是在SQL Script中:

define table function MY_TABLE_FUNCTION
returns
{
  A : some_type;
  B : some_type;
}
implemented by method
  cl_my_table_function=>provide_data_for_tf_test;

Finally, you provide the ABAP class that implements the table function:最后,您提供实现 table 函数的 ABAP 类:

CLASS cl_my_table_function DEFINITION
    PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_amdp_marker_hdb.
    CLASS-METHODS provide_data FOR TABLE FUNCTION MY_TABLE_FUNCTION.
ENDCLASS.

CLASS cl_my_table_function IMPLEMENTATION.

  METHOD provide_data 
    BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT
    USING some_table.

    RETURN
      SELECT A, B
       FROM some_table;

  ENDMETHOD.

ENDCLASS.

When you do something like this, spare some extra time to test the client handling.当你做这样的事情时,留出一些额外的时间来测试客户端处理。 This combination of ways often brings down the automatic client additions ABAPers know from the SELECT statement and regular CDS views.这种方法的组合通常会降低 ABAPers 从 SELECT 语句和常规 CDS 视图中知道的自动客户端添加。 There is a chance that you will need annotations like @ClientHandling: { type: #CLIENT_DEPENDENT } on the involved CDS views and have the table function provide the CLIENT or MANDT columns explicitly.您可能需要在涉及的 CDS 视图上使用@ClientHandling: { type: #CLIENT_DEPENDENT }注释,并让表函数明确提供 CLIENT 或 MANDT 列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM