ABAP 填充内表
📊 内表填充概述
填充方式
在内部表中,填充包括选择、插入和追加等功能。本章重点介绍INSERT和APPEND语句。
填充策略
graph TD
A[内表填充] --> B[单行操作]
A --> C[批量操作]
B --> B1[INSERT]
B --> B2[APPEND]
B --> B3[MODIFY]
C --> C1[批量插入]
C --> C2[循环填充]
C --> C3[SELECT结果]
🔧 INSERT语句
功能
INSERT语句用于将单个行或一组行插入内部表。
语法
1
| INSERT <work_area_itab> INTO <internal_tab> INDEX <index_num>.
|
语法详解
| 参数 |
说明 |
示例 |
|
工作区,提供要插入的数据 |
wa_customer |
|
目标内部表 |
lt_customers |
| INDEX |
插入位置(可选) |
INDEX 2 |
执行逻辑
- 插入位置:当使用INDEX子句时,插入行之后的行的索引号增加1
- 边界情况:如果internal_tab包含 - 1行,新行添加在表的末尾
- 返回码:当SAP系统成功地将行添加到内部表时,SY-SUBRC变量设置为0
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| REPORT zcuslist1.
DATA: BEGIN OF itable1 OCCURS 4, f1 LIKE sy-index, END OF itable1.
* 填充初始数据 DO 4 TIMES. itable1-f1 = sy-index. APPEND itable1. ENDDO.
* 在索引2位置插入行 itable1-f1 = -96. INSERT itable1 INDEX 2.
* 输出结果 LOOP AT itable1. WRITE / itable1-f1. ENDLOOP.
* 在符合条件的行之前插入 LOOP AT itable1 WHERE f1 >= 3. itable1-f1 = -78. INSERT itable1. ENDLOOP. SKIP.
* 再次输出 LOOP AT itable1. WRITE / itable1-f1. ENDLOOP.
|
输出示例
1 2 3 4 5 6 7 8 9 10 11 12 13
| 1 96- 2 3 4
1 96- 2 78- 3 78- 4
|
INSERT注意事项
- 性能开销:执行每个insert语句后,系统会重新编制所插入的行下面的所有行
- 大型表插入:当在大型内部表的顶部附近插入行时,会引入开销
- 推荐做法:准备另一个包含要插入的行的表,并使用批量插入
- 循环内插入:在循环内插入不会立即影响内部表,而是在下一个循环传递中生效
🔧 APPEND语句
功能
APPEND语句用于向现有内部表添加单个行或行。此语句从工作区复制单个行,并将其插入内部表中的最后一个现有行之后。
语法
1
| APPEND <record_for_itab> TO <internal_tab>.
|
语法详解
| 参数 |
说明 |
示例 |
|
要添加的记录 |
wa_customer 或 INITIAL LINE |
|
目标内部表 |
lt_customers |
工作区来源
| 来源 |
说明 |
| 标题行 |
使用内表的标题行作为源 |
| 其他工作区 |
使用与内表行具有相同结构的字段字符串 |
| INITIAL LINE |
添加一个空行,包含初始值 |
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| REPORT zcuslist1.
DATA: BEGIN OF linv OCCURS 0, Name(20) TYPE c, ID_Number TYPE i, END OF linv. DATA table1 LIKE TABLE OF linv.
* 填充数据 linv-Name = 'Melissa'. linv-ID_Number = 105467. APPEND linv TO table1.
* 输出结果 LOOP AT table1 INTO linv. WRITE: / linv-name, linv-ID_Number. ENDLOOP.
|
输出示例
⚠️ 键和排序注意事项
标准表和排序表
- 非唯一键:使用非唯一键将行附加到标准和排序表中,无论表中是否存在具有相同键的行
- 重复条目:可能发生重复条目
排序表的特殊情况
graph LR
A[排序表] --> B[唯一键检查]
A --> C[排序顺序检查]
B --> B1[重复条目→运行时错误]
C --> C1[违反顺序→运行时错误]
避免运行时错误
1 2 3 4 5 6
| * 检查唯一性后插入 IF line_exists( table1 WITH TABLE KEY Name = 'Test' ). WRITE: / '记录已存在'. ELSE. APPEND linv TO table1. ENDIF.
|
💡 填充最佳实践
1. 批量操作
1 2 3 4 5 6 7 8 9
| * 使用批量INSERT提高性能 DATA: lt_new_data TYPE TABLE OF ty_customer, wa_new TYPE ty_customer.
* 填充临时表 APPEND wa_new TO lt_new_data.
* 批量插入 INSERT LINES OF lt_new_data INTO TABLE lt_customers.
|
2. 条件填充
1 2 3 4
| * 只在条件满足时填充 IF lv_flag = abap_true. APPEND wa_customer TO lt_customers. ENDIF.
|
3. 错误处理
1 2 3 4 5 6 7 8 9 10 11 12 13
| * 检查插入结果 INSERT wa_customer INTO TABLE lt_customers.
IF sy-subrc <> 0. CASE sy-subrc. WHEN 1. WRITE: / '插入失败:重复键'. WHEN 2. WRITE: / '插入失败:违反排序'. WHEN OTHERS. WRITE: / '插入失败:未知错误'. ENDCASE. ENDIF.
|
4. 性能优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| * 在循环外填充工作区 DO 1000 TIMES. wa_customer-id = sy-index. wa_customer-name = 'Customer' && sy-index. APPEND wa_customer TO lt_customers. ENDDO.
* 推荐:先填充临时表,再批量插入 DATA: lt_temp TYPE TABLE OF ty_customer.
DO 1000 TIMES. wa_customer-id = sy-index. APPEND wa_customer TO lt_temp. ENDDO.
INSERT LINES OF lt_temp INTO TABLE lt_customers.
|
📊 INSERT vs APPEND
| 特性 |
INSERT |
APPEND |
| 插入位置 |
指定索引位置 |
末尾 |
| 性能 |
较慢(需要重新索引) |
较快 |
| 灵活性 |
高(可指定位置) |
低(只能末尾) |
| 适用场景 |
特定位置插入 |
简单追加 |
| 系统开销 |
大(移动后续行) |
小(直接追加) |