【ABAP】关于内表的常用操作知识
一、内表的前言在 ABAP 中长期使用的数据存储在关系数据库表格中。除了数据库表格还可创建仅在程序运行时间内存在的内表。同时针对这张内表 ABAP 提供了针对内表的不同操作。例如搜索、附加、插入或删除行。该特征项使得内表使用起来十分方便同时还支持动态编程。总结下来内表是在ABAP程序中定义的一种数据结构用于在内存中存储和处理数据。它类似于数据库中的表或其他编程语言中的数组或列表可以存储一系列具有相同数据结构的数据行。内表中的数据是临时的仅在程序运行期间存在。ABAP运行时系统动态地管理内表的大小。每个独立的数据集合在内表中称为一个表项或表行而一行中独立的组件对应于内表中的字段或列。二、带表头行 VS 不带表头行ABAP 内表分为带表头行和不带表头行两种是新旧语法的核心区别也是新手开发者高频踩坑点。现代 ABAP 开发官方完全弃用带表头行内表仅旧程序遗留使用。2.1 概念定义带表头行内表定义内表时系统自动生成一个同名隐式工作区表头行无需手动声明工作区可直接操作。无表头行内表仅生成纯数据表体必须手动显式定义独立工作区/字段符号操作数据是现代开发标准规范。2.2 两种内表核心对比对比项带表头行的内表不带表头行的内表工作区有隐式表头行同名结构体可隐式使用需显式声明独立工作区常用WA或LS_前缀引用内体需用itab[]引用内表本身itab通常指表头行直接用itab引用内表本身优点编码简洁历史上广泛使用结构清晰不易混淆更符合现代编程规范缺点容易混淆内体和表头行存在歧义行为需额外声明工作区官方建议不推荐在新程序中使用参考资料明确说明推荐使用2.3 语法定义对比带表头行内表DATA: BEGIN OF itab OCCURS 10, col1 TYPE i, col2 TYPE i, END OF itab.不带表头行内表TYPES: BEGIN OF ty_line, col1 TYPE i, col2 TYPE i, END OF ty_line. DATA: itab TYPE TABLE OF ty_line, ls_line TYPE ty_line.三、内表类型概览ABAP 标准内表分为标准表、排序表、哈希表三者存储结构、访问逻辑、性能、适用场景完全不同。内表类型访问方式主要特点适用场景标准表索引或关键字线性存储索引访问快通用场景常需索引访问小数据量查询排序表索引或关键字按关键字自动排序二分查找需数据有序常关键字访问中等数据量查询哈希表仅关键字哈希算法访问关键字访问最快大数据量仅需关键字访问大数据量查询四、核心操作解析4.1. 查询READ从内表中读取数据。4.1.1 索引读取访问标准表、排序表专属无表头的行 读取单行 READ TABLE itab INDEX 1 INTO wa. IF sy-subrc 0. 读取成功 ENDIF. 读取多行循环 LOOP AT itab INTO wa FROM 1 TO 10. 处理数据 ENDLOOP.带表头的行READ TABLE itab INDEX 3. IF sy-subrc 0. WRITE: itab-col1, itab-col2. ENDIF.4.1.2 关键字访问所有表类型哈希表必须使用 TABLE KEY语法不支持模糊关键字读取 标准表/排序表 READ TABLE itab INTO wa WITH KEY k1 A k2 B. 或新语法 READ TABLE itab INTO wa WITH TABLE KEY k1 A k2 B. 哈希表必须使用TABLE KEY READ TABLE itab INTO wa WITH TABLE KEY k1 A k2 B.4.1.3 二分查找仅排序表硬性前提内表必须已按查询关键字排序否则结果错乱SORT itab BY col1 ASCENDING. READ TABLE itab INTO ls_line WITH KEY col1 3 BINARY SEARCH.注意仅当内表已按查询关键字排序时使用。4.2 增加APPEND/INSERT4.2.1 APPEND 追加单行无表头行标准写法必须显式工作区ls_line-col1 1. ls_line-col2 2. APPEND ls_line TO itab.带表头行隐式使用表头行无需工作区itab-col1 1. itab-col2 2. APPEND itab.4.2.2 INSERT 插入指定位置支持索引插入排序表/标准表可用哈希表不支持索引1索引插入标准表、排序表无表头行 插入到指定位置 INSERT wa INTO itab INDEX 5. 插入到表尾标准表 INSERT wa INTO TABLE itab. 或 itab VALUE #( BASE itab ( wa ) )推荐标准表使用 INSERT INTO TABLE 追加到末尾。带表头行不常用itab-col1 0. itab-col2 0. INSERT itab INDEX 1.2按关键字插入排序表、哈希表 排序表自动按关键字排序插入 INSERT wa INTO TABLE itab. 哈希表按哈希键值插入 INSERT wa INTO TABLE itab.注意排序表插入时若破坏排序顺序会触发异常。4.3 修改MODIFY更新内表中现有行的内容。4.3.1 索引修改标准表、排序表无表头的行 修改指定索引行 MODIFY itab FROM wa INDEX 3. 修改当前循环行 LOOP AT itab INTO wa WHERE condition. wa-field new_value. MODIFY itab FROM wa. ENDLOOP.带表头的行itab-col1 10. itab-col2 20. MODIFY itab INDEX 3.4.3.2 关键字修改所有表类型 标准表/排序表 MODIFY TABLE itab FROM wa. 哈希表 MODIFY TABLE itab FROM wa.推荐使用MODIFY TABLE按关键字修改更安全高效。4.4. 删除DELETE从内表中移除行。4.4.1 索引删除标准表、排序表 删除单行 DELETE itab INDEX 2. 删除多行 DELETE itab FROM 5 TO 10.4.4.2 关键字删除所有表类型 删除匹配关键字的行 DELETE TABLE itab FROM wa. 或 DELETE itab WHERE k1 A.4.4.3 条件删除 删除满足条件的所有行 DELETE itab WHERE field value. 循环中删除 LOOP AT itab INTO wa WHERE condition. DELETE itab. ENDLOOP.4.5 内表初始化与清空CLEAR itab无表头行清空内表带表头行同时清空内表表头行 CLEAR itab[]仅清空内表数据保留表头行仅旧语法用 REFRESH itab清空内表数据等价 CLEAR itab[] FREE itab清空数据 释放内存大数据量处理后推荐使用4.6 内表复制、计算与比较 复制内表 itab2 itab1. MOVE itab1 TO itab2. 比较内表 IF itab1 itab2. 内容相同 ENDIF. 追加整个内表 APPEND LINES OF itab1 TO itab2. 追加指定范围的行从第2行到第5行 APPEND LINES OF itab1 FROM 2 TO 5 TO itab2. 将itab1内容追加到itab2保留itab2原有内容 itab2 VALUE #( BASE itab2 ( LINES OF itab1 ) ). 或使用CORRESPONDING操作符 itab2 CORRESPONDING #( BASE ( itab2 ) itab1 ). 使用VALUE初始化并添加数据 DATA(itab) VALUE ty_itab( ( k1 A k2 B ) ( k1 C k2 D ) ). 使用CORRESPONDING复制结构匹配字段 itab2 CORRESPONDING #( itab1 ). 使用REDUCE汇总数据 total REDUCE i( INIT sum 0 FOR wa IN itab NEXT sum sum wa-amount ).4.7 COLLECT 语句COLLECT 语句用于向内表添加行其核心特点是根据标准关键字进行汇总如果关键字已存在则累加数字字段如果不存在则像 APPEND 一样添加新行。COLLECT wa INTO itab [ON OVERFLOW statement].wa源工作区包含要添加或汇总的数据。itab目标内表。ON OVERFLOW statement可选部分。当内表因内存不足等原因无法添加数据时会执行 statement 中的代码。示例 1简单数据收集假设我们有一个包含员工信息的内表其中有员工编号empno和工资salary字段我们要收集员工的工资总和。TYPES: BEGIN OF ty_employee, empno TYPE i, salary TYPE p DECIMALS 2, END OF ty_employee. DATA: gt_employee TYPE STANDARD TABLE OF ty_employee, gs_employee TYPE ty_employee. 模拟数据填充工作区 gs_employee-empno 1001. gs_employee-salary 5000.00. COLLECT gs_employee INTO gt_employee. gs_employee-empno 1001. gs_employee-salary 3000.00. COLLECT gs_employee INTO gt_employee. 此时gt_employee 中对于员工编号 1001 的记录salary 字段会自动累加为 8000.00示例 2使用 ON OVERFLOWTYPES: BEGIN OF ty_product, product_id TYPE char10, quantity TYPE i, END OF ty_product. DATA: gt_product TYPE STANDARD TABLE OF ty_product, gs_product TYPE ty_product. gs_product-product_id P001. gs_product-quantity 10. COLLECT gs_product INTO gt_product ON OVERFLOW MESSAGE 内存不足无法收集数据 TYPE E.在上述示例中如果 COLLECT 操作因为内表内存不足等问题无法执行就会显示错误消息 “内存不足无法收集数据”。注意事项当使用 COLLECT 时内表的行类型必须定义了唯一的关键字。如果工作区 wa 中的数据与内表 itab 中已有的某一行在关键字字段上的值完全相同那么 wa 中与内表关键字不同的字段值会累加到内表对应行的相应字段上前提是这些字段的数据类型支持累加操作如数值类型。如果内表是哈希表COLLECT 操作会基于哈希算法快速定位和处理数据效率较高。对于大数据量的收集操作哈希表通常比标准表性能更好。五、实践总结与注意事项5.1 类型选择需要索引访问 → 标准表需要有序数据且频繁关键字查询 → 排序表仅需关键字访问且数据量大 → 哈希表5.2 性能优化避免在循环中频繁使用READ TABLE ... BINARY SEARCH大量数据插入时考虑使用COLLECT语句汇总使用SORT语句前确认内表类型排序表已自动排序5.3 错误处理始终检查sy-subrcREAD、INSERT、DELETE等操作排序表插入时注意排序顺序避免non-unique key异常哈希表不支持索引操作使用前确认访问方式5.4 代码可读性使用描述性字段名复杂操作添加注释优先使用新语法如VALUE、REDUCE等简化代码