写点什么

SAP AMDP 介绍 - ABAP 托管的 HANA 数据库过程

作者:Jerry Wang
  • 2022 年 8 月 22 日
    上海
  • 本文字数:2290 字

    阅读完需:约 8 分钟

SAP AMDP 介绍 - ABAP 托管的 HANA 数据库过程

随着 ABAP 7.40 SP05 的发布,SAP ABAP 引入了一种新的应用开发范式,即所谓的 Code Pushdown.


传统的 ABAP 应用开发方式,即下图左边的 Data to Code, 数据库仅仅作为数据的静态存储仓库,ABAP 应用开发人员通过 Open SQL 等方式将数据从数据库层读取到 ABAP 应用层,再在 ABAP 应用层进行数据处理。



Code Pushdown 意味着一种编程理念的转变,即上图右边所示,将密集的数据计算从 ABAP 应用层下推到 HANA 数据库层,从而充分发挥 HANA 数据库高性能的数据处理能力。


要实现 Code Pushdown,SAP HANA 数据库必须提供一种技术,能够允许 ABAP 开发人员在 HANA 数据库层直接编写应用逻辑。这些应用逻辑可以实现在所谓的数据库过程(Database Procedure)里,实现语言为 SAP HANA SQLScript.



我们可以把数据库过程简单地类比成一个只能进行数据库读写及相关处理的函数,能接收任意多个输入参数和定义输出参数,存放数据库操作的结果。参数的类型既可以是标量式类型,比如 integer, double, varchar 等,也可以是 table 类型。


使用 ABAP Development Tool, 我们可以选择两种不同的方式来实现数据库过程。第一种,即本文标题提及的 AMDP, 第二种为数据库过程代理(Database Procedure Proxy), 不在本文讨论范围之内。


AMDP, 顾名思义,即在 ABAP 层进行 HANA 数据库过程的实现和生命周期(lifecycle)的管理。开发人员通过位于 ABAP 层的 ABAP Development Tool, 编写 HANA SQLScript 作为 AMDP 的实现体,以此达到在 ABAP 层直接消费 HANA 数据库层原生功能的目的。



具体到实现环节,在 ABAP 层内何种类型的开发对象里编写 HANA SQLScript 呢?答案仍然是 ABAP 类的方法内,只不过是在一种声明了特定接口的 ABAP 类,用 AMDP 特定的 ABAP 关键字修饰的方法内。继续沿用 ABAP 类方法来开发 AMDP, 使得传统 ABAP 应用开发人员除了熟悉 HANA SQLScript 语法外,无需付出额外的学习成本。这种特殊的 ABAP 类方法,作为 HANA SQLScript 的承载容器,使得 AMDP 同其他普通的 ABAP 开发对象一样,采取统一的 ABAP 传输管理,生命周期管理,代码缺陷修复和升级管理方式。



除了 AMDP 之外,数据库过程代理是另一种 HANA 数据库过程的实现方式。这种方式首先在 HANA repository 里创建一个 HANA 原生的数据库过程,再到 ABAP 层创建一个代理指向前者,在 ABAP 应用里通过使用该代理对象,消费 HANA 仓库里的原生数据库过程。同 AMDP 相比,这种方式需要在 HANA 层进行原生开发,因此在实际的开发场景中,SAP 更推荐使用 AMDP.


实际上 AMDP 不是一个新事物,早在 2013 年这个功能刚刚随着 ABAP 7.40 SP05 发布之时,我就第一时间试用并且写了一篇学习笔记:


https://blogs.sap.com/2013/12/10/an-example-of-amdp-abap-managed-database-procedure-in-740/



看个具体的例子,还是使用广大 ABAP 开发人员喜闻乐见的 SFLIGHT 系列模型。


本文例子的完整代码,可以通过点击文末的“阅读原文”获得。


首先,AMDP 类只能在 ABAP Development Tool 里进行开发,在 SAP GUI 里可以用只读的方式浏览源代码,但无法修改:



前面概述章节里提到,AMDP 是实现在一个特殊的 ABAP 类之内,这个 ABAP 类的特殊之处就体现在,它需要声明一个 Marker Interface(标记接口,有的文档又称之为 Tag Interface, 标签接口):IF_AMDP_MARKER_HDB.



这个标记接口扮演了现代 Java 开发中的 Annotation 的角色,即作为元数据,告知 ABAP 编译期和运行时,这个 ABAP 类作为容器,存放 AMDP 的实现。


顺便提一句,除了 IF_AMDP_MARKER_HDB,ABAP 还有很多其他的标记接口,比如表明一个 ABAP 类支持序列化操作的接口,IF_SERIALIZABLE_OBJECT:



以及标注一个接口需要被 BAdI Definition 使用的 IF_BADI_INTERFACE. 我们在创建或修改 ABAP 新式 BAdI 时,任何定义在 BAdI Definition 中的接口,如果没有声明接口 IF_BADI_INTERFACE,会无法通过 ABAP 语法检查。



因为 ABAP 缺乏像 Java 那样能够从语言级别直接使用注解(Annotation)进行元数据定义的特性,因而采用了标记接口这种方式。


在 Java 基于 Spring 框架的开发里,Annotation 几乎随处可见。JDK1.5 之后引入的 Annotation,能声明在 Java 包、类、字段、方法、局部变量、方法参数等资源之上,达到维护元数据的目的,既灵活又方便。然而 Java 诞生之初,在 JDK1.5 之前,标记接口也是 Java 唯一能够从语言层级进行元数据维护的方式。


下图是 Java 用来定义一个类能够支持序列化操作的标记接口 Serializable, 对应着 ABAP 的标记接口 IF_SERIALIZABLE_OBJECT.



再回到本文的例子 ZCL_JERRY_AMDP_DEMO, main 方法里就执行一个逻辑:从 SFLIGHTS 系列的模型里读取数据。



方法 get_flights 从数据库表里读取数据,然后调用另一个方法 convert_currency,直接在 HANA 数据库层面进行货币转换,再把结果返回给 ABAP 层的输出参数 result.



前面提到过,AMDP 实现在一个特殊 ABAP 类的特殊方法里。特殊的 ABAP 类,前文已经介绍过,该类必须声明标记接口 IF_AMDP_MARKER_HDB. 而 AMDP 方法同普通 ABAP 方法相比的特殊之处,体现在 BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT 这些 ABAP 关键字上:



上图红色区域的 ABAP 关键字,表明被修饰的 ABAP 方法是一个 AMDP 的容器,AMDP 的实现语言为 HANA SQLScript,实现体内以只读方式访问了两张数据库表/dmo/flight 和/dmo/carrier, 以及另一个实现货币转换功能的名为 convert_currency 的 AMDP.


这个 AMDP 的逻辑主要是接收之前从/dmo/flight 和/dmo/carrier 两张表做内连接后得到的数据作为输入,同时消费 HANA SQLScript 里一个内置函数 convert_currency, 将数据库里的机票价格转换成以欧元 EUR 为单位的值。



convert_currency 函数的参数定义:


https://help.sap.com/viewer/4fe29514fd584807ac9f2a04f6754767/2.0.03/en-US/d22d746ed2951014bb7fb0114ffdaf96.html



执行结果:



后续笔者有时间会介绍 AMDP 的调试和性能分析等内容,感谢阅读。

发布于: 21 小时前阅读数: 3
用户头像

Jerry Wang

关注

🏆InfoQ写作平台-签约作者🏆 2017.12.03 加入

SAP成都研究院开发专家,SAP社区导师,SAP中国技术大使。2007 年从电子科技大学计算机专业硕士毕业后加入 SAP 成都研究院工作至今。工作中使用 ABAP, Java, JavaScript 和 TypeScript 进行开发。

评论

发布
暂无评论
SAP AMDP 介绍 - ABAP 托管的 HANA 数据库过程_数据库_Jerry Wang_InfoQ写作社区