SAP HANA 上进行 ABAP 开发:简介
-
本文档有哪些内容?
本博客的重点是概述引入 HANA 数据库后 ABAP 中的新编程技术。重点是就 ABAP 开发人员为何以及如何开始将代码转换为使用新编码技术提供指导。 -
谁应该阅读这本书?
这里的目标受众是希望对 HANA 上的 ABAP 编程有基本了解并理解为什么要选择这些新功能的 ABAP 开发人员。 -
本博客涵盖的领域:
代码到数据范例、OpenSQL、CDS 视图、AMDP。
让我们开始吧!
前言
SAP ABAP 多年来一直在快速发展。随着 S/4HANA 的推出,ABAP 逐渐成为一门更令人印象深刻、更富有成效的语言。如果你问我 ABAP 是如何改进的,答案就是 “代码到数据 ”范式。
什么是 “代码到数据 ”范式?
传统的方法包括将数据从数据库引入到我们的演示服务器,进行数据密集型计算和过滤,然后将过滤后的数据呈现给用户。
新的 HANA 方法是将我们的代码推送到所有数据所在的数据库层,在数据库层进行计算,然后只将相关记录带到演示服务器。
由于采用了 C2D 模式,将大量数据传输到表现层时因延迟而造成的延迟被大大消除,因此即使是非常大的数据集也能获得很高的性能。
为了更好地理解这一点,让我用一个任何 ABAP 开发人员都很容易理解的基本场景来说明:
示例场景: 一份 ALV 报表可返回 “所有 ”供应商的主数据及其地址,包括处于活动状态的供应商、未标记为集中删除的供应商、未标记为 “所有 ”公司代码下删除的供应商、未标记为 “所有 ”采购组织下删除的供应商。
在这种情况下,由于要获取所有供应商、所有公司代码和所有采购组织的数据,性能会受到影响。由此产生的报表将需要后台运行,在这种情况下,传统的 ABAP 报告流程将按如下方式获取数据:
在这里,如果不在选择语句下使用连接,呈现层将与表交互几次。此外,由于系统中存在大量供应商数据,使用连接从这些表中获取数据的速度也会非常慢。那么,该如何提高性能呢?
答:- 使用以下方法编写 PushDown 代码
- OpenSQL Programming(尽管目前还很有限)
- CDS 视图
- ABAP 管理数据库程序
让我们逐一访问上述功能,看看它们如何与 HANA DB 配合使用。
- OpenSQL Programming
使用 OpenSQL 编程,您可以在 ABAP 代码中编写 OpenSQL 语法。
在使用 OpenSQL 编写代码时,选择语句中的字段用逗号分隔,所有主变量都使用“@
”符号转义,可以在单个语句中使用“| |
”进行连接,等等,不一而足。
上述情况的写法如下:
REPORT zact_vendor_osql.
SELECT a~lifnr,
b~bukrs,
c~ekorg,
d~name1,
d~city1,
d~region,
d~country,
d~post_code1
INTO TABLE @DATA(gt_vendor)
FROM lfa1 AS a
INNER JOIN lfb1 AS b ON b~lifnr = a~lifnr
INNER JOIN lfm1 AS c ON c~lifnr = a~lifnr
LEFT OUTER JOIN adrc AS d ON d~addrnumber = a~adrnr
WHERE a~loevm EQ @abap_false
AND a~sperr EQ @abap_false
AND a~sperm EQ @abap_false
AND a~node1 EQ @abap_false
AND b~sperr EQ @abap_false
AND c~loevm EQ @abap_false
AND c~sperm EQ @abap_false.
GET RUN TIME FIELD data(lv_end_time).
DATA(lv_time) = lv_end_time - lv_start_time.
cl_demo_output=>display_data(EXPORTING value = gt_vendor
name = |Duration { lv_time } ms|.
结果如下:
在这里,您可以看到报告运行了 1621 毫秒,并返回了所需的结果。
这只是我举的一个非常基本的例子,但在实时场景中,你可能会做一些聚合,或者在选择过程中翻译一些数据,或者根据一些字段对结果集进行分组。虽然目前使用 OpenSQL 时代码推送的机会有限,但自 7.4 版本发布以来,这方面的语法已得到增强。SAP 有许多语法可以在代码中使用,以提高性能。首先,您可以在 ABAP 术语表中找到非常详细的示例和代码片段。
- Core Data Services (CDS) Views
SAP 推出了一种新的数据建模基础架构,称为核心数据服务或 CDS。利用 CDS,数据模型是在数据库服务器而不是应用服务器上定义和使用的。因此,表格结果视图是在数据库级别创建的。CDS 与 OPEN SQL 完全兼容,可以使用 Eclipse Oxygen 等 ABAP 开发工具编写。报表和 AMDP 也可以使用这些数据。
上述代码将在 Eclipse 中创建为数据定义,并定义如下:
@AbapCatalog.sqlViewName: 'ZCDS_ACT_VEN' //SE11 SQL view name
@AbapCatalog.Complier.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'CDS View data definition'
define view ZCDS_ACT_VENDOR //CDS view name
as select from lfa1 as a
inner join lfb1 as b on a.lifnr = b.lifnr and b.sperr = ''
inner join lfm1 as c on a.lifnr = c.lifnr and c.sperm = ''
left outer join adrc as d on a.adrnr = d.addrnumber
{
key a.lifnr,
key b.bukrs,
key c.ekorg,
d.name1,
d.city1,
d.region,
d.country,
d.post_code1
} where a.loevm = '' and a.sperr = '' and a.sperm = ''
结果为:
CDS 视图在 39 毫秒内返回结果。厉害吗?没错。
现在,CDS 视图也可以通过参数或关联来创建。如果有固定的结果集和一些需要传递的输入参数,可以选择创建带参数的 CDS。
如果在视图中需要处理许多表,并且希望保持结果集的灵活性,也可以创建带关联的 CDS,以满足类似的需求。
- ABAP Managed Database Procedures (AMDP)
AMDP 顾名思义是直接在数据库中运行的数据库程序,直接用 ABAP 编写。AMDP 是使用 AMDP 类编写的。下面以上述情况为例,说明如何创建 AMDP 类。接口 “IF_AMDP_MARKER_HDB
”将 AMDP 类与其他类区分开来。
类定义:
CLASS zcl_act_vendor_amdp DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb.
TYPES: BEGIN OF ty_vendor,
lifnr TYPE lifnr,
bukrs TYPE bukrs,
ekorg TYPE ekorg,
name1 TYPE name1,
city1 TYPE adrc-city1,
region TYPE adrc-region,
country TYPE adrc-country,
post_code1 TYPE adrc-post_code1,
END of ty_vendor,
tt_vendor TYPE SORTED TABLE OF ty_vendor WITH NON-UNIQUE KEY lifnr bukrs ekorg.
METHODS get_vendors_amdp IMPORTING VALUE(lv_clnt) type mandt
EXPORTING VALUE(lt_vendor) type tt_vendor.
ENDCLASS.
同样,AMDP 类的实现将使用 “BY DATABASE PROCEDURE FOR <database> LANGUAGE <language>
”语法定义方法。在我们的例子中,数据库是 HDB(HANA DB),语言始终是 SQLSCRIPT。
CLASS zcl_act_vendor_amdp IMPLEMENTATION.
METHOD get_vendors_amdp
BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY USING lfa1 lfb1 lfm1 adrc.
lt_vendor = SELECT DISTINCT a.lifnr,
b.bukrs,
c.ekorg,
d.name1,
d.city1,
d.region,
d.country,
d.post_cdoe1
FROM lfa1 AS a
INNER JOIN lfb1 AS b
ON b.mandt = a.mandt AND b.lifnr = a.lifnr AND
b.loevm = '' AND b.sperr = ''
INNER JOIN lfm1 AS c
ON c.mandt = a.mandt AND c.lifnr = a.lifnr AND
c.loevm = '' AND c.sperm = ''
LEFT OUTER JOIN adrc AS d
ON d.client = a.mandt AND d.addrnumber = a.adrnr
WHERE a.mandt = lv_clnt
AND a.loevm = ''
AND a.sperr = ''
AND a.sperm = '';
ENDMETHOD.
ENDCLASS.
然后,可以在 ABAP 程序中使用该 AMDP 类,以实现代 push down 功能。
REPORT z_act_vendor_amdp.
TYPES: BEGIN OF ty_vendor,
lifnr TYPE lifnr,
bukrs TYPE bukrs,
ekorg TYPE ekorg,
name1 TYPE name1,
city1 TYPE adrc-city1,
region TYPE adrc-region,
country TYPE adrc-country,
post_code1 TYPE adrc-post_code1,
END OF ty_vendor.
DATA: gt_vendors TYPE SORTED TABLE OF ty_vendor WITH NON-UNIQUE KEY lifnr bukrs ekorg.
GET RUN TIME FIELD DATA(gv_start).
DATA(go_ref) = NEW zcl_act_vendor_amdp( ).
go_ref->get_vendors_amdp( EXPORTING lv_clnt = sy-mandt
IMPORTING lt_vendor = gt_vendors ).
GET RUN TIME FIELD DATA(gv_end).
DATA(gv_time) = gv_end - gv_start.
cl_demo_output=>display_data( value = gt_vendors
name = |Duration { gv_time }ms| ).
结果:
选择 OpenSQL 还是 CDS 还是 AMDP?
任何开发人员都会遇到的一个问题是,如何在这三种编程技术中做出选择。
在上述示例中,您可以看到性能表现为 CDS > OpenSQL > AMDP。
这是否意味着在上述情况下,创建 CDS 是最佳选择?不尽然!
如果我不重复使用 CDS 视图,那么 openSQL 也是同样有效的选择。
还要注意的是,CDS 视图和 AMDP 只能使用 ABAP 开发工具(如 Eclipse Oxygen)创建。请参考以下链接,了解如何在系统中安装 eclipse:
https://tools.hana.ondemand.com/#abap
在选择上述三种编程技术时,没有任何规则可循。这完全取决于需求以及需要处理哪些数据和如何处理数据。不过,以下几点可以帮助我们了解如何做出最有效的选择。
在以下情况选择 “OPEN SQL”:
- 表格选择是程序特定的,不会重复使用
- 当您没有 ABAP 开发工具来创建 CDS 或 AMDP 时。这两者可以在图形用户界面中使用,但不能在图形用户界面中创建。
- 当相关数据不涉及密集计算,并且可以通过 OpenSQL 轻松管理时。
- 当您有一个棘手的选择屏幕,其中有许多选择选项,这些选项也将作为单个值传递。
在以下情况下选择 CDS 视图:
- 视图可在其他视图或程序中重复使用。
- 涉及来自不同数据源的大量数据时。
- 熟悉如何编写注释以增强 CDS 视图。
- 只需要单一结果集。
在以下情况下选择 AMDP:
- 您精通 SQL 脚本,因为您的全部代码都将使用 SQL 脚本编写,而编译器无法判断运行时 SQL 脚本错误(如除以零)。
- 必须处理跨客户端数据时,因为 AMDP 本身无法处理客户端数据。
- 需要多个结果集时。
这篇博客旨在向您介绍 HANA 的功能以及您可以利用新技术做些什么。我对任何初学者的建议都是亲手操作一个系统并尝试一下。