ABAP 填充内表

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

执行逻辑

  1. 插入位置:当使用INDEX子句时,插入行之后的行的索引号增加1
  2. 边界情况:如果internal_tab包含 - 1行,新行添加在表的末尾
  3. 返回码:当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注意事项

  1. 性能开销:执行每个insert语句后,系统会重新编制所插入的行下面的所有行
  2. 大型表插入:当在大型内部表的顶部附近插入行时,会引入开销
  3. 推荐做法:准备另一个包含要插入的行的表,并使用批量插入
  4. 循环内插入:在循环内插入不会立即影响内部表,而是在下一个循环传递中生效

🔧 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.

输出示例

1
Melissa     105467

⚠️ 键和排序注意事项

标准表和排序表

  • 非唯一键:使用非唯一键将行附加到标准和排序表中,无论表中是否存在具有相同键的行
  • 重复条目:可能发生重复条目

排序表的特殊情况



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
插入位置 指定索引位置 末尾
性能 较慢(需要重新索引) 较快
灵活性 高(可指定位置) 低(只能末尾)
适用场景 特定位置插入 简单追加
系统开销 大(移动后续行) 小(直接追加)