目前笔者大部分时间,都投入了日常开发工作的 Angular 技术研究中。
剩下的业余时间,主要花费在笔者下面五套 SAP 开发技术教程的持续更新上:
SAP ABAP 开发教程
SAP UI5 开发教程
SAP OData 开发教程
SAP Fiori Elements 开发教程
SAP CDS View 开发教程
本专栏每天 5 分钟,介绍一个 ABAP 相对冷门的知识点。
前两篇文章:
到底哪些单词不能作为 ABAP 透明表名称使用?
聊聊 ABAP 里感叹号 ! 的用法
今天我们来聊聊 ABAP 的内表(internal table).
众所周知,ABAP OPEN SQL 可以使用 SELECT 关键字,从数据库表读取数据。
SELECT * FROM 数据库表
对于内表的读取来说,只支持 READ TABLE,LOOP AT 等操作。
但是到了 ABAP 7.52 之后,内表也能作为数据源之一,出现在 OPEN SQL 的 SELECT FROM 后面了。
SAP 官方帮助文档提到:
SELECT FROM @内表变量名称 的语法,把驻留在应用服务器内存中的内表临时「伪装」成数据库表,支持大多数 Open SQL 子句,包括 WHERE、ORDER BY、INNER JOIN、GROUP BY,甚至可以与真实数据库表混合 JOIN.
Open SQL 引擎把内表视作「驻留在内存里的虚拟数据库表」,并自动把内表每列的 ABAP 数据类型,映射到 ABAP Dictionary 里的对应内置类型。
如果内表列本身已经使用了 ABAP DDIC 类型,则直接复用原定义。
这一新的特性,让 ABAP 开发者能够在不借助辅助数据库表的情况下,仅仅通过 OPEN SQL 就能完成复杂的数据过滤、聚合和联结逻辑。
看一些例子。
构造一个内表,包含 id 和 number 两个字段。id 在 A 到 Z 的大写字母里随机选择一个,number 从 1 到 100 的整数里随机选择一个。
TYPES:BEGIN OF line, id TYPE c LENGTH 1, number TYPE i,END OF line.
DATA(rnd) = cl_abap_random_int=>create( seed = CONV i( sy-uzeit ) min = 1 max = 100 ).
itab = VALUE #(FOR i = 1 UNTIL i > 25 ( id = substring( val = sy-abcde off = i len = 1 ) number = rnd->get_next( ) ) ).
上面的代码构造了一个包含 25 条记录的内表。
现在想把内表里所有 number > 50 的行项目筛选出来。
一行 SELECT 语句搞定。
SELECT * FROM @itab AS numbers WHERE number > 50 ORDER BY id INTO TABLE @DATA(result).
输出效果如下:
再来看一个内表出现在 SELECT 语句里参与和数据库表进行 JOIN 操作的例子。
在 ABAP 7.52 之前,OPEN SQL 语句里如果想实现内表和数据库表混用的操作,只能使用 SELECT FROM 数据库表名 FOR ALL ENTRIES IN @内表名 的语法。
ABAP 7.52 之后可以直接在 SELECT 语句里将内表和数据库表进行 JOIN 操作:
DATA itab TYPE TABLE OF scarr WITH KEY mandt carrid.
itab = VALUE #( ( carrid = 'LH' carrname = 'L.H.' ) ( carrid = 'UA' carrname = 'U.A.' ) ).
SELECT scarr~carrid, scarr~carrname, spfli~connid FROM @itab AS scarr INNER JOIN spfli ON scarr~carrid = spfli~carrid INTO TABLE @DATA(result).
cl_demo_output=>display( result ).
执行结果,内表 itab 的 carrid 字段同数据库表 scarr 的 carrid 字段进行 JOIN, 最后的结果包含了内表的 carrid, carrname 以及数据库表的 connid 字段值。
当我们熟练掌握 SELECT … FROM @itab 的新语法之后,就能把 ABAP 内表与数据库表的操作无缝融合:既享受 OPEN SQL 强大的过滤、聚合能力和良好的可读性,又避免了多余的数据搬运与临时表维护。
领取专属 10元无门槛券
私享最新 技术干货