SAP ABAP CDS 详解

发布时间:2024年01月21日

前言

Core data services(核心数据服务),简称CDS,是一个基础结构,数据库开发人员可以使用它来创建应用程序服务向UI客户端公开的底层(持久)数据模型。使用CDS,数据模型是在数据库服务器上定义和使用的,而不是在应用程序服务器上。CDS还提供了超越传统数据建模工具的功能,包括对概念建模和关系定义、内置功能和扩展的支持。
在这里插入图片描述

架构概述

● 数据库层——这一层可以配置大多数流行的数据库,如Oracle, SAP HANA等。但为了得到最好的效果,推荐使用SAP HANA。
● 应用层——这一层包含ABAP Backend 和 SAP Gateway,使用RFC调用进行集成。
● 表示层——这一层包含SAP Fiori用户界面,用于向最终用户公开应用程序。
在这里插入图片描述

ABAP CDS

ABAP CDS提供了一个框架,用来在ABAP应用服务器的中央数据库定义和使用语义数据模型。它基于ABAP字典管理的数据定义语言(DDL)和数据控制语言(DCL)。因此,CDS Entity或CDS Views的增强在CDS数据定义中被定义为源代码。
要定义一个CDS Entity,你首先需要创建一个DDL源( DDL source)作为相关的开发对象,使用该对象可以使用ABAP工作台的标准功能——例如语法检查,激活,传输等功能。你可以在Eclipse ADT或SAP HANA studio ADT的基于文本的DDL编辑器中来定义CDS Entity。
在这里插入图片描述

ABAP CDS VIEW

可以运行在除了HANA之外的其他数据库平台之上,使用ADT(ABAP Development Tool)工具通过DDL语言进行定义。通过对数据库表添加assciation和annotation等方式定义带有丰富语义的视图对象,供ODATA和SAPUI5使用,同时也可以在ALV报表中作为数据的来源。
● 在通常的ABAP CDS视图开发过程中,我们通过编辑器(通常是ADT)在ABAP层声明了我们的字段结构和annotations。激活后,系统会自动地在数据库层生成所有的SQL视图。
● 使用ABAP CDS声明语句DEFINE VIEW,可以为现有的数据库表和视图或ABAP字典中的其他CDS Views定义一个CDS Views。CDS Views用于定义SQL View的结构,并表示在一个或多个字典表或字典视图上的投影。
在这里插入图片描述
选择Define View类型并新建
在这里插入图片描述
在这里插入图片描述

注:SQL View和CDS Entity是同一个命名空间的一部分。因此,必须为SQL View和CDS Entity分配不同的名称。
激活CDS View后,在ABAP字典中会创建以下对象:
● 实际的CDS Entity (ZVSDE002_DDL_004)
● SQL View (ZVSDE002_004)
在这里插入图片描述

ABAP CDS Table Function
● 在ABAP CDS Table Function的开发过程中,我们将字段结构、参数(可选)、association等通过类/方法定义为实体。通过AMDP我们可以直接在ABAP层写存储过程,并且把它封装在类/方法中。
● 因为AMDP直接运行数据库脚本,所以需要做几个额外的步骤并且会使用到脚本语言(在HANA中即SQL Script)。
在这里插入图片描述

选择Table Function类型并新建
在这里插入图片描述

编辑生成的实体,包含以下内容:
● 字段
● 类
● 方法

@EndUserText.label: 'table function demo'
define table function Zdemo
with parameters
    @Environment.systemField: #CLIENT
    clnt      : abap.clnt,
    langu     : langu,
    c_desc_01 : lfart
returns
{
  client       : abap.clnt;
  airline_code : s_carr_id;
  airline_name : s_carrname;
  cities_to    : abap.string;
}
implemented by method
  zcl_demo_amdp=>mt_set_value_demo;

当然,现在zcl_demo_amdp类还不存在,需要创建它
● 让类包含IF_AMDP_MARKER_HDB接口。这一步会把你的ABAP类转换为AMDP类,并且允许在类的方法内写存储过程。
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb.
在方法实现中我们需要引入某些配置选项:
● BY DATABASE FUNCTION: 会将方法标记为table function,还有一个选项是通过 BY DATABASE PROCEDURE标记为存储过程.
● FOR HDB: 设定数据库类型为HDB (HANA数据库).
● LANGUAGE SQLSCRIPT: HANA数据库存储的语言.
● OPTIONS READ-ONLY: 存储过程内不允许修改数据.
● USING: 定义table function中消费的数据库表、视图或者存储过程。在本例中,只访问SFLIGHTS 视图

METHOD mt_set_value_demo
    BY DATABASE FUNCTION
    FOR HDB
    LANGUAGE SQLSCRIPT
    OPTIONS READ-ONLY
    USING sflights.
  ENDMETHOD.

● AMDP的优点之一是你可以将SELECT的查询结果传输至"内表",并且可以执行新的SELECT来读取它的数据。让我们应用这一功能的优点,并且将第一个SELECT的语句的查询结果命名为itab_cities.

itab_cities =
      SELECT DISTINCT 
             sflights.mandt    as client,
             sflights.carrid   as airline_code,
             sflights.carrname as airline_name,
             sflights.cityto   as city_to
        FROM sflights;

● 在第二个SELECT中,我们要从itab_cities中读取数据并且实现数据库方法STRING_AGG来聚合多个城市和航空公司。为了实现这一功能我们需要基于Client,Airline Code和Name字段GROUP BY条目。

RETURN
      SELECT client,
             airline_code,
             airline_name,
             STRING_AGG(city_to, ', ' ORDER BY city_to) as cities_to
        FROM :itab_cities
       GROUP BY client,
                airline_code,
                airline_name;

注:table function应永远有返回参数,所以记着在最后一个SELECT语句前放一个RETURN语句。另外,注意我们将字段名转换为前文中ABAP CDS Table Function声明的字段名,如果你没有提供一个合适的别名,激活的时候编译器会给出提示。
所以类的最终版本是这样的:

CLASS zcl_demo_amdp DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_amdp_marker_hdb.

    CLASS-METHODS:
      mt_set_value_demo FOR TABLE Zdemo.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_demo_amdp IMPLEMENTATION.
  METHOD mt_set_value_demo
    BY DATABASE FUNCTION
    FOR HDB
    LANGUAGE SQLSCRIPT
    OPTIONS READ-ONLY
    USING sflights.

    itab_cities =
      SELECT DISTINCT 
             sflights.mandt    as client,
             sflights.carrid   as airline_code,
             sflights.carrname as airline_name,
             sflights.cityto   as city_to
        FROM sflights;

    RETURN
      SELECT client,
             airline_code,
             airline_name,
             STRING_AGG(city_to, ', ' ORDER BY city_to) as cities_to
        FROM :itab_cities
       GROUP BY client,
                airline_code,
                airline_name;
  ENDMETHOD.
ENDCLASS.

在实际程序中直接根据条件查询table function即可。

      SELECT *
        FROM  Zdemo
        WHERE client = @sy-mandt
        INTO TABLE @DATA(lt_001).

ABAP CDS 访问控制
ABAP CDS支持基于数据控制语言(DCL)的访问控制。ABAP CDS的访问控制进一步限制了从ABAP CDS中的CDS实体返回的数据。
如果为CDS实体定义了CDS角色,那么每当使用Open SQL或SADL查询去访问对象时,都会隐式地校验访问条件(除非给访问控制参数@AccessControl.authorizationCheck赋值#NOT_ALLOWED来禁用访问控制)。如果启用了访问控制(赋值:##CHECK),则只有满足访问条件的数据才能访问到。
每个CDS角色都由一段单独的CDS源代码定义。此源代码只能通过ABAP Development Tools (ADT)修改。当激活后,CDS角色在ABAP字典中是一个全局内部对象。定义CDS角色的源代码与定义CDS Entity(CDS View 或 CDS Table Function)的源代码是在不同的编辑器中编辑的。
假设我们已经定义好了一个CDS View,如下:

@AbapCatalog.sqlViewName: ‘Z_T100_SABDEMOS’
@AccessControl.authorizationCheck: #CHECK.

define view z_t100_sabapdemos
  as select from t100
    { * }  where arbgb = ‘SABAPDEMOS’

然后,我们可以通过DCL(数据控制语言)为上述视图创建一个CDS角色(如下所示)。

@MappingRole: true

define role role_name {
  grant select on z_t100_sabapdemos
  where ( arbgb ) =  aspect pfcg_auth ( s_develop, objname,
                                                  objtype = ‘MSAG’,
                                                  actvt  = ’03’ )
                     and sprsl= ‘E’ ; }

在上述示例中:
● 条件语句" sprsl=‘E’ "限制了只能通过英语访问
● 关于PFCG条件方面,pfcg_auth ( s_develop … ) 语句将CDS角色关联到了一个经典权限对象s_develop,CDS访问控制运行时从中生成一个访问条件,该条件评估当前用户对该对象的授权。在这里,预定义的pfcg_auth将权限字段objname关联到了视图字段arbgb。另外,检查用户的权限是否符合授权字段objtype和actvt的固定值。
HANA CDS
由于HANA需要直接在数据库内开发应用,使用标准SQL语言比如CREATE TABLE和CREATE VIEW等,已不能满足需要定义带有语义属性(比如Annotation)的数据库表、视图、类型等,因此HANA CDS应运而生。
ABAP CDS与HANA CDS的区别
有了ABAP CDS和HANA CDS,我们就有了基于同一规范的两个实现。这两者是十分相似的,但是并不100%等同。如果你知道CDS的DDL,你应当可以理解两种不同风格下的CDS实体的定义。但是在规则上,你并不能从ABAP不加修改地复制DDL源放到HANA上,反之亦然。另一方面,由于HANA CDS只作用在SAP HANA上,ABAP CDS则是开放的,因此,ABAP CDS中存在着某些在HANA CDS中不存在的限制(出于同样的原因,OPEN SQL也比原生SQL的限制更多)。内建函数就是个好例子。ABAP CDS中的像CURRENCY_CONVERSION一样的内建函数必须在任何数据库平台可用,并且——这点非常重要——必须在所有平台有相同的表现。表达式也是这样,比如算术表达式,聚合或者CAST表达式。在ABAP CDS中想要发布这样的一个功能,必须让所有的平台都加进去。而且这也是ABAP CDS至今不能提供SAP HANA的所有SQL功能的原因(但是这项工作还在进行…)。另一方面,它是开放的!因此也有某些ABAP特性例如客户端处理、表缓存目前在HANA CDS中不可用,但是在ABAP中可以使用。

CDS的优点

  1. 语义丰富的数据模型
  2. 领域特定语言(DDL,QL,DCL)
  3. 声明式,接近概念性思维
  4. 完全基于SQL
  5. 可直接在CDS中使用“标准SQL”功能(如连接,联合,内置函数)
  6. 兼容各种数据库
  7. 生成和管理的SQL视图
  8. SAP HANA中的本机集成
  9. 可以作为不同特定领域框架的共同基础,例如 UI,Analytics,Odata,BW。
  10. 代码下推
  11. 表函数
  12. 丰富的内置SQL函数
  13. 可扩展
  14. 模型级别上的扩展
  15. 元模型层面上的注释
  16. 可测试

OPEN SQL与CDS的对比

  • 效率:因为HANA底层(SAP S4 HANA版本)的特性,已经使得传统Open SQL变快,双方的性能没有明显区别。我们想让SQL更快,首先考虑的还是限制数据库到应用层的数据传输量,尽可能地将检索条件指明。
  • 使用场景:这取决于可重用性。 如果是只需要一次的功能,则无需创建CDS视图。 举个简单的例子,如果一个需求是希望在某个表检索后,其中某个字段要经过简单的计算然后输出,并且这样的数据,在一个项目中的很多场景中都会用到。如果用传统ABAP,我们会先Open SQL取数,然后在LOOP中编辑,最后使用。如果使用CDS View,我们可以直接将这些取数逻辑都放在CDS Entity里,并且这个Entity是可以在SE11检索到,直接当做一个表来使用。
文章来源:https://blog.csdn.net/zkl519/article/details/135594923
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。