Appearance
SAP ABAP 开发内表详解
任何编程语言都有不断发展的生命周期。ABAP语言也是从COBOL
语言衍生而来,到现在为止又导入了很多新的技术。过程式编程一面向对象编程一适用BSP(JAVA Script 与ABAP组合)
→WebDynpro
→BPP
……谁都无法预测将来会导入哪种新的技术。因为这种趋势,若只关心学习新技术,也许所有的精力全都花费在了追逐新技术上。本书的主要目的不在于学习高级技术。那些高级技术通过SAP提供的范例模板可以充分理解。当然,在用户立场上考虑,掌握 ALV等技术非常重要。但是任何语言最重要的莫过于基础,要着重理解何为ABAP语言,即理解其基本原理和基础概念。比起在前端显示华丽的画面,更为重要的是在后端正确设计出用户要求的数据模型。另外,还要学会正确定义数据类型相对应的内表类型,及学会实现既正确又快速的读取数据库表数据的 SOL语句。
1. 内表概要
内表(Internal Table)是ABAP中用于临时存储和处理结构化数据的动态内存表。其核心特性包括:
- 动态内存分配:自动扩展/收缩内存空间。
- 结构化存储:存储具有相同字段结构的数据行。
- 高效操作:支持快速数据检索、排序和聚合。
典型应用场景
- 从数据库表读取数据并缓存处理
- 批量数据传输(如接口开发)
- 复杂业务逻辑中的中间结果存储
2. 内表与表头
表头(Header Line)
- 定义:旧版ABAP中声明内表时自动生成的隐式工作区。
- 问题:容易引发逻辑混淆(如隐式操作导致数据覆盖)。
- 现代替代方案:使用显式工作区(Work Area)替代表头。
代码对比
abap
" ❌ 旧式声明(带表头)"
DATA: BEGIN OF itab OCCURS 0,
matnr TYPE matnr,
maktx TYPE maktx,
END OF itab.
" ✅ 推荐声明(分离工作区)"
TYPES: BEGIN OF ty_material,
matnr TYPE matnr,
maktx TYPE maktx,
END OF ty_material.
DATA: gt_material TYPE STANDARD TABLE OF ty_material,
gs_material TYPE ty_material.
三、内表类型
类型 | 访问方式 | 特点 | 适用场景 |
---|---|---|---|
标准表 | 索引或关键字(线性搜索) | 默认类型,插入速度快 | 频繁插入/顺序访问 |
排序表 | 关键字(二分搜索) | 数据按关键字自动排序 | 需要有序数据且频繁查找 |
哈希表 | 关键字(哈希算法) | 唯一键值,查找速度最快 | 高频精确查找(无重复键) |
类型特性详解
标准表(STANDARD TABLE)
- 技术特性:
- 使用线性搜索(
LOOP AT
或READ TABLE
)访问数据,插入操作仅需追加到末尾 - 支持非唯一键,适用于动态增长的临时数据集
- 使用线性搜索(
- 典型应用:
- 日志记录场景(如快速插入事务流水数据)
- 需要遍历全部数据的批量处理程序
- 技术特性:
排序表(SORTED TABLE)
- 技术特性:
- 通过二分搜索(
BINARY SEARCH
)实现高效查找,时间复杂度为O(log n) - 插入新数据时会自动维护排序顺序,可能触发数据重排
- 通过二分搜索(
- 典型应用:
- 配置表查询优化(如国家代码与名称映射表)
- 需要范围查询的统计报表生成(如按时间区间筛选订单)
- 技术特性:
哈希表(HASHED TABLE)
- 技术特性:
- 哈希算法直接定位数据地址,查找时间复杂度为O(1)
- 键字段必须唯一,内存消耗高于其他表类型
- 典型应用:
- 主键检索高频场景(如通过物料号快速获取库存信息)
- 数据去重处理(如合并重复交易记录)
- 技术特性:
声明示例:
abap
" 标准表"
DATA: gt_std_tab TYPE STANDARD TABLE OF ty_structure
WITH NON-UNIQUE KEY field1.
" 排序表"
DATA: gt_sorted_tab TYPE SORTED TABLE OF ty_structure
WITH UNIQUE KEY field1.
" 哈希表"
DATA: gt_hashed_tab TYPE HASHED TABLE OF ty_structure
WITH UNIQUE KEY field1.
四. 内表速度比较
操作类型 | 标准表 | 排序表 | 哈希表 |
---|---|---|---|
索引访问 | O(1) | O(log n) | 不支持 |
关键字查找 | O(n) | O(log n) | O(1) |
插入数据 | O(1)(尾部) | O(n)(维护顺序) | O(1)(哈希计算) |
删除数据 | O(n) | O(n) | O(1) |
关键说明
标准表(数组)
- 索引访问:通过下标直接访问元素,时间复杂度为 O(1) 。
- 插入尾部:仅需在数组末尾追加元素,无需移动其他元素 。
- 删除操作:需将后续元素前移以填补空缺,时间复杂度为 O(n) 。
排序表(有序结构)
- 关键字查找:利用二分查找实现 O(log n) 的高效搜索 。
- 维护顺序:插入/删除时需调整元素位置以保证有序性,时间复杂度为 O(n) 。
哈希表
- 关键字查找:通过哈希函数直接定位存储位置,平均时间复杂度为 O(1) 。
- 冲突处理:采用链地址法或开放地址法,保证插入/删除操作的平均时间复杂度为 O(1) 。
- 空间特性:牺牲空间效率换取时间效率,需管理负载因子避免性能退化 。
性能对比总结
- 索引场景优先选择标准表:若需高频随机访问,数组的 O(1) 时间复杂度最优 。
- 查询场景优先选择哈希表:关键字匹配场景下,哈希表性能显著优于线性结构 。
- 动态数据慎用排序表:频繁插入/删除时,排序表的维护成本较高 。
性能对比与选型建议
维度 | 标准表 | 排序表 | 哈希表 |
---|---|---|---|
插入效率 | 最优(直接追加) | 中等(需维护排序) | 最差(需计算哈希) |
查询效率 | 最差(线性遍历) | 中等(二分搜索) | 最优(直接寻址) |
内存占用 | 低 | 中等 | 高 |
适用数据量 | 中小型动态数据集 | 中型有序数据集 | 大型静态数据集 |
使用建议
- 大数据量查询:优先选择哈希表或排序表。
- 频繁插入/删除:标准表尾部操作效率更高。
- 需要有序输出:必须使用排序表。
五. 常用内表命令
ABAP 内表操作命令速查表
命令 | 说明 | 示例 |
---|---|---|
APPEND | 添加单行到标准表末尾 | APPEND gs_data TO gt_data. |
INSERT | 插入单行到索引表的指定位置 | INSERT gs_data INTO gt_data INDEX 2. |
MODIFY | 根据索引/键值修改行数据 | MODIFY gt_data FROM gs_data INDEX 3. |
DELETE | 删除指定索引或满足条件的行 | DELETE gt_data INDEX 4. |
READ TABLE | 通过键值或索引读取单行数据 | READ TABLE gt_data WITH KEY id = '100' INTO gs_data. |
LOOP AT | 遍历内表并逐行处理数据 | LOOP AT gt_data INTO gs_data. ... ENDLOOP. |
SORT | 按字段升序/降序排列内表 | SORT gt_data BY field1 ASCENDING. |
FREE | 清空内表并释放内存 | FREE: gt_data. |
补充说明
APPEND
- 仅适用于标准表(STANDARD TABLE),向表尾追加数据。
- 若需批量追加数据,可用
APPEND LINES OF
语法。
INSERT
- 对索引表(INDEX TABLE)可直接指定位置插入,哈希表(HASHED TABLE)需通过键值插入。
- 示例中
INDEX 2
表示插入到第2行位置。
MODIFY
- 若未指定索引或键值,默认修改当前循环行(需在
LOOP AT
内使用)。 - 支持批量修改:
MODIFY gt_data FROM TABLE lt_changes
.
- 若未指定索引或键值,默认修改当前循环行(需在
DELETE
- 支持条件删除:
DELETE gt_data WHERE field1 = 'X'
. - 批量删除重复项:
DELETE ADJACENT DUPLICATES FROM gt_data COMPARING field1
.
- 支持条件删除:
READ TABLE
- 若使用二分查找需先排序:
READ TABLE gt_data BINARY SEARCH...
- 检查是否成功读取:
IF sy-subrc = 0. ... ENDIF.
- 若使用二分查找需先排序:
SORT
- 多字段排序:
SORT gt_data BY field1 ASCENDING field2 DESCENDING.
- 稳定排序(保持原顺序):
SORT ... STABLE
.
- 多字段排序:
FREE
- 等价于
CLEAR: gt_data.
但更彻底释放内存。 - 联合清空:
FREE: gt_data, lt_temp.
- 等价于
高级操作
abap
" 批量插入"
INSERT LINES OF gt_source INTO TABLE gt_target.
" 内表去重"
DELETE ADJACENT DUPLICATES IN gt_data COMPARING field1.
" 使用字段符号(Field Symbol)动态操作"
FIELD-SYMBOLS: <fs_line> TYPE ty_structure.
LOOP AT gt_data ASSIGNING <fs_line>.
<fs_line>-field2 = 'Updated'.
ENDLOOP.
六. 内表创建方法
方法1:直接定义结构
abap
TYPES: BEGIN OF ty_employee,
emp_id TYPE char10,
name TYPE string,
dept TYPE char4,
END OF ty_employee.
DATA: gt_employees TYPE TABLE OF ty_employee.
方法2:参考数据库表
abap
DATA: gt_mara TYPE STANDARD TABLE OF mara.
方法3:动态类型创建
abap
DATA: gt_dynamic TYPE REF TO data.
CREATE DATA gt_dynamic TYPE TABLE OF (dyn_table_name).
ASSIGN gt_dynamic->* TO FIELD-SYMBOL(<ft_dynamic>).
方法4:使用类型池(Type Pools)
abap
TYPE-POOLS: slis.
DATA: gt_list TYPE slis_t_listheader.
七、性能优化技巧
- 避免嵌套循环:使用 SORTED TABLE + READ TABLE BINARY SEARCH 替代。
- 批量操作优先:用 INSERT LINES OF 替代逐行插入。
- 合理选择表类型:超过1万行数据时避免使用标准表的全表扫描。
- 释放未使用的内表:及时调用 FREE 释放内存。