Core data services(以下简称 CDS)可以指两样东西, 一个是 HANA CDS,一个是 ABAP CDS 。
如我们所知,HANA CDS 只支持 HANA 数据库,ABAP CDS 理论上支持多种数据库供应商,结果是,ABAP CDS 相比之下要少一些功能。因此,在某些情况下,无法使用 ABAP CDS 解决问题时,可以使用一种变通的方法,即通过 ABAP Managed Database Procedures (AMDP) 创建 ABAP CDS Table Function。本文链接: http://www.cnblogs.com/hhelibeb/p/8057788.html
注:本文的主要理论内容已经包含在之前的 AMDP 介绍文章: ABAP 中的 AMDP(ABAP-Managed Database Procedures ) 中,相比它,本文更像一个 step by step 教程。
在通常的 ABAP CDS 视图开发过程中,我们通过编辑器(通常是 ADT)在 ABAP 层声明了我们的字段结构和 annotations。激活后,系统会自动地在数据库层生成所有的 SQL 视图。
ABAP CDS 视图提供多种 SQL 命令和函数的支持,如果你想要了解细节和全部的可用特性,建议你看这篇文章: ABAP CDS Feature Matrix 。
在 ABAP CDS Table Function 的开发过程中,我们将字段结构、参数(可选)、association 等通过类 / 方法定义为实体。通过 AMDP 我们可以直接在 ABAP 层写存储过程,并且把它封装在类 / 方法中,更多介绍可以看之前的文章: ABAP 中的 AMDP(ABAP-Managed Database Procedures 。
因为 AMDP 直接运行数据库脚本,所以需要做几个额外的步骤并且会使用到脚本语言(在 HANA 中即 SQL Script)。稍后在示例部分我们会讨论配置的细节。
通过上文介绍的这两种开发技术,我们可以开始开发一个技术示例了。按本文的例子做下去,你将会可以创建你自己的 ABAP CDS Table Function,并且为不能直接通过 ABAP CDS 实现的需求提供解决方案。为了实现示例,我们会使用数据库视图 SFLIGHTS,这一视图提供了航班连接的细节。
每个航空公司提供世界上不同城市的航班连接,用户想要在单一字段中看到某一特定航空公司支持的所有城市,内容以逗号分隔。因为每家航空公司的城市数是不同的,我们需要一个逻辑来拼接城市们,无论有查询结果多少条数据。
在常规的 ABAP CDS 内我们可以使用 CONCAT 函数,但是使用它的时候,我们需要定义固定数量的字段,既然 CDS 视图不能此处需要的处理动态逻辑,要如何处理呢?
这是一个使用 ABAP CDS Table Function 的绝佳场景,因为我们可以通过简单的数据库函数 STRING_AGG(String Aggregation)。这个功能在 SQL Script 中可用,但是目前还是不支持 ABAP CDS 视图。
打开你的 HANA Studio(或者 ADT),创建一个新的 Core Data Services -> Data Definitio。
选择 project,package 并且定义名字和描述:
选择传输请求,然后点击 Next。在模板中选择最后一个选项 "Define Table Function with Parameters",然后点击 Finish:
编辑生成的实体,包含以下内容:
结果应该是:
- define table function ZDEMO_FLIGHTS_TABLE_FUNCTION
- returns
- {
- client : abap.clnt;
- airline_code : s_carr_id;
- airline_name : s_carrname;
- cities_to : abap.string;
- }
- implemented by method
- ZCL_FLIGHTS_DEMO_CDS=>FLIGHTS_CONNECTIONS;
当然,现在 ZCL_FLIGHTS_DEMO_CDS 还不存在。下一步,让我们创建它:
让类包含 IF_AMDP_MARKER_HDB 接口。这一步会把你的 ABAP 类转换为 AMDP 类,并且允许了在类的方法内写存储过程。
- PUBLIC SECTION.
- INTERFACES if_amdp_marker_hdb.
在方法实现中我们需要引入某些配置选项:
- METHOD flights_connections
- BY DATABASE FUNCTION
- FOR HDB
- LANGUAGE SQLSCRIPT
- OPTIONS READ-ONLY
- USING sflights.
- <<你的代码>>
- ENDMETHOD.
让我们准备好查询分割逻辑的两个 SELECT 语句。
第一个 SLECT 需要获取 Client, Airline Code, Airline Name 和 City To 字段,并通过 DISTINCT 关键字去重,因为我们会找到在不同的连接日期的相同的航空公司的城市记录,如图:
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 声明的字段名,如果你没有提供一个合适的别名,激活的时候编译器会给出提示。类 ZCL_FLIGHTS_DEMO_CDS 的最终版本是这样的:
- CLASS zcl_flights_demo_cds DEFINITION
- PUBLIC
- FINAL
- CREATE PUBLIC .
- PUBLIC SECTION.
- INTERFACES if_amdp_marker_hdb.
- CLASS-METHODS:
- flights_connections FOR TABLE FUNCTION zdemo_flights_table_function.
- PROTECTED SECTION.
- PRIVATE SECTION.
- ENDCLASS.
- CLASS zcl_flights_demo_cds IMPLEMENTATION.
- METHOD flights_connections
- 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.
在 Data Preview 中的结果:
来源: http://www.cnblogs.com/hhelibeb/p/8057788.html