下面我们来聊聊 ABAP.
SAP note 1230076 Generation of ABAP loads: Tips for the analysis
介绍了一个工具程序:RSDEPEND。这个 note 提到,一个即便看起来最简单的 ABAP Hello World 报表,其实也依赖于许多标准的 Repository 对象,这些依赖我们假定称其为 A,B,C.
假设 A,B,C 其中有任何一个有改动产生,比如 A 是一个 include 程序,里面使用到了一个 DDIC 结构,在某个时刻,系统导入了一个传输请求(Transport Request), 里面包含了针对这个 DDIC 结构的更改,那么此时这个最简单的 Hello World 报表的 load 就成为了 obsolete 状态。在重新执行该报表之前,ABAP Runtime(中文译成 ABAP 运行时)会自动做一个 load invalidation
操作,生成一个最新版本的 load.
什么是 ABAP load?看 ABAP help 里的官方定义:
In the ABAP environment, a load describes a binary representation of a repository object which is optimized for fast access, in the memory or on the database.
翻译成中文:ABAP load 是 Repository 对象的二进制表现形式,针对 ABAP 环境的快速访问而做过特别优化,可以存储在数据库表中或者加载于内存里。
我们用一个实际的例子来理解 ABAP 报表激活和运行时发生的事情。
创建一张非常简单的透明表 ZLOADTEST:
写一个简单的报表,命名 为ZTESTLOAD.
报表的源代码以压缩的格式存储在表 REPOSRC 的 DATA 字段里。
测试报表的源代码很简单,把表里的数据全部读取出来:
激活这个简单的报表(是的,在 ABAP 世界里,我们习惯说激活,而不是编译)。激活后生成的 ABAP load 存储在表 REPOLOAD 的字段 LDATA 和 QDATA 里。
这两个字段存储的内容就是前面 ABAP help 提到的 ABAP load 在数据库表中的存储形式。
菜单 Goto->Navigate to->Switch to Classic Debugger:
Goto->System Areas->Internal Information:
在 System Area 区域输入CONT,就能在下图的 NAME 列看到 ABAP load 里包含的指令。当然同开源的 JVM 不同,JVM 字节码指令集在网上能够查到,而这些 ABAP load 的指令是 SAP internal 的,因此不能在这里做解释。
然后执行前面提到的工具报表 RSDEPEND, 输入参数 program name = ZTESTLOAD, 得到结果,其中测试报表的 ABAP Load 时间戳为 07:21:02, 这个报表依赖的标准Include 有:
由此看出,每一个标准的 ABAP 报表都自动包含了这些 include.
如果开发人员显式地再包含其中任意一个,会遇到语法错误: Module %_PF_STATUS is already defined as a OUTPUT module.
大家觉得这个 <REPINI>
是不是很像前文 C 语言部分提到的 #include<stdio.h>
?
下面我们再做几轮测试。