Core data services
(核心数据服务),简称CDS
,是一个基础结构,数据库开发人员可以使用它来创建应用程序服务向UI客户端公开的底层(持久)数据模型。使用CDS,数据模型是在数据库服务器上定义和使用的,而不是在应用程序服务器上。CDS还提供了超越传统数据建模工具的功能,包括对概念建模和关系定义、内置功能和扩展的支持。
● 数据库层——这一层可以配置大多数流行的数据库,如Oracle, SAP HANA等。但为了得到最好的效果,推荐使用SAP HANA。
● 应用层——这一层包含ABAP Backend 和 SAP Gateway,使用RFC调用进行集成。
● 表示层——这一层包含SAP Fiori用户界面,用于向最终用户公开应用程序。
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。
可以运行在除了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中可以使用。