ABAP提供了三种类型的内表, 即:标准表(Standard Table), 排序表(Sorted Table), 哈希表(Hashed Table)。在未声明内表类型时,系统会将类型默认为标准表。
然而,标准表其实并不适用于所有的业务场景,我们应当根据实际的需求,定义使用合适类型的内表。
1. 内表的类型
让我们回顾下不同内表的访问方式。标准表和排序表是可以既通过index访问,有可通过key访问;而哈希表只能通过键值访问。
三种内表的特征如下表:
内表类型 | 访问方式 | 主键 | 推荐方式 | 查找算法 |
---|---|---|---|---|
标准表 | 索引访问、键值访问 | NON-UNIQUE KEY | 索引访问 | 顺序查找法、二分查找法 |
排序表 | 索引访问、键值访问 | NON-UNIQUE KEY 、UNIQUE KEY | 键值访问 | 二分查找法 |
哈希表 | 键值访问 | UNIQUE KEY | 键值访问 | 哈希算法 |
2. 使用原则
- 标准表:当数据量较小(<100 entries), 并既需要使用索引访问,又需要通过不同的键值访问时,可以定义使用标准表。当通过键值访问时,应当使用SORT + BINARY SEARCH的语法,也即使用二分查找算法替代顺序查找。在排序时,应尽量明确指定排序的字段。
- 排序表:当访问内表的主要方式是通过“主键访问”时,应定义使用排序表。排序表的主键可以不唯一。
- 哈希表:完全通过主键访问数据,并且在数据量较大时,应使用Hash表。在数据量不大时,Hash表的查找速度和Sorted表类似。在某种程度上,Hash表的性质等同于主键唯一的Sorted表。
3. 注意事项
- 避免通过顺序查找的方式访问含有大量数据的内表;
- 避免在嵌套的循环中,通过顺序查找的方式访问内表;
- 无论哪一种内表,都要避免内表数据过大的情况发生,因为CPU的内存是有限的,无限制增加内表的数据量会至系统DUMP;
- 对于大数量的情形,应采用分批次、分包的处理方式。
4. 示例
示例1: 对于标准表,使用二分查找替代顺序查找
DATA: lt_sflight TYPE STANDARD TABLE OF sflight,
ls_sflight TYPE sflight.
*-------------------------------------------------------
* 标准表
SELECT * FROM sflight
INTO TABLE lt_sflight UP TO 100 ROWS
WHERE carrid = 'AA'
OR carrid = 'LH'.
*-------------------------------------------------------
* standard table - sequential read
*-------------------------------------------------------
READ TABLE lt_sflight INTO ls_sflight
WITH KEY carrid = 'AA'
connid = '0064'
fldate = '20180403'.
IF sy-subrc = 0.
WRITE: / ls_sflight-carrid, ls_sflight-planetype.
ENDIF.
*-------------------------------------------------------
* standard table - read with binary search
*-------------------------------------------------------
SORT lt_sflight BY carrid connid fldate.
READ TABLE lt_sflight INTO ls_sflight
BINARY SEARCH
WITH KEY carrid = 'AA'
connid = '0064'
fldate = '20180403'.
IF sy-subrc = 0.
WRITE: / ls_sflight-carrid, ls_sflight-planetype.
ENDIF.
示例2: 使用主键不唯一的排序表
DATA: lt_sflight_sorted TYPE SORTED TABLE OF sflight WITH NON-UNIQUE KEY carrid connid fldate,
ls_sflight TYPE sflight.
*-------------------------------------------------------
* 排序表
*-------------------------------------------------------
SELECT * FROM sflight
INTO TABLE lt_sflight_sorted UP TO 100 ROWS
WHERE carrid = 'AA'
OR carrid = 'LH'.
READ TABLE lt_sflight_sorted INTO ls_sflight
WITH TABLE KEY carrid = 'AA'
connid = '0064'
fldate = '20180403'.
IF sy-subrc = 0.
WRITE: / ls_sflight-carrid, ls_sflight-planetype.
ENDIF.
示例3: 定义并使用哈希表
DATA: lt_sflight_hashed TYPE HASHED TABLE OF sflight WITH UNIQUE KEY carrid connid fldate,
ls_sflight TYPE sflight.
*-------------------------------------------------------
* 哈希表
*-------------------------------------------------------
SELECT * FROM sflight
INTO TABLE lt_sflight_hashed UP TO 100 ROWS
WHERE carrid = 'AA'
OR carrid = 'LH'.
READ TABLE lt_sflight_hashed INTO ls_sflight
WITH TABLE KEY carrid = 'AA'
connid = '0064'
fldate = '20180403'.
IF sy-subrc = 0.
WRITE: / ls_sflight-carrid, ls_sflight-planetype.
ENDIF.