ABAP Open SQL 语法整理:SELECT、JOIN、增删改与常见坑


文章封面

ABAP Open SQL 语法整理:SELECT、JOIN、增删改与常见坑

SAP 新文档中更常用的名称是 ABAP SQL,老项目和很多教材仍称 Open SQL。本文按日常 ABAP 开发的习惯整理,示例优先使用较新的 @ 主机变量写法。

1. Open SQL 是什么

Open SQL/ABAP SQL 是 ABAP 访问数据库的标准 SQL 层:

  • 面向 ABAP Dictionary 中定义的表、视图、CDS View 等数据源。
  • 尽量屏蔽底层数据库差异,但较新 ABAP SQL 功能可能与数据库平台和 ABAP 版本有关。
  • 常用语句包括 SELECTINSERTUPDATEMODIFYDELETE
  • 和 Native SQL 不同,Open SQL 不直接写数据库厂商专用 SQL;需要数据库专用语法时才用 EXEC SQL ... ENDEXEC 或 AMDP。

2. 现代 Open SQL 基本规则

2.1 主机变量使用 @

ABAP 变量出现在 SQL 语句里时,推荐或需要加 @

DATA(lv_carrid) = 'LH'.

SELECT FROM sflight
  FIELDS carrid, connid, fldate
  WHERE carrid = @lv_carrid
  INTO TABLE @DATA(lt_flights).

常见位置:

WHERE field = @lv_value
WHERE field IN @s_field
INTO @DATA(ls_row)
INTO TABLE @DATA(lt_rows)
UP TO @lv_rows ROWS
OFFSET @lv_offset

2.2 推荐显式字段列表

优先写需要的字段,少用 SELECT *

SELECT FROM mara
  FIELDS matnr, mtart, matkl
  WHERE mtart = @lv_mtart
  INTO TABLE @DATA(lt_mara).

2.3 表字段和别名

表别名用 AS,字段访问常用 ~

SELECT FROM vbak AS h
  INNER JOIN vbap AS i
    ON i~vbeln = h~vbeln
  FIELDS h~vbeln, h~erdat, i~posnr, i~matnr
  WHERE h~auart = @lv_auart
  INTO TABLE @DATA(lt_items).

2.4 常见执行结果字段

  • sy-subrc = 0:通常表示成功或读取到数据。
  • sy-subrc = 4:通常表示未找到数据、未更新/删除任何行,或插入时存在键冲突等情况,具体看语句。
  • sy-dbcnt:数据库语句影响或读取的行数。
SELECT SINGLE FROM mara
  FIELDS matnr, mtart
  WHERE matnr = @lv_matnr
  INTO @DATA(ls_mara).

IF sy-subrc = 0.
  " found
ENDIF.

3. SELECT 语法骨架

推荐记忆这个骨架:

SELECT [SINGLE]
  FROM data_source [AS alias]
  [FIELDS [DISTINCT] field_list]
  [WHERE sql_condition]
  [GROUP BY group_fields]
  [HAVING group_condition]
  [ORDER BY sort_fields]
  [INTO target]
  [UP TO n ROWS]
  [OFFSET o].

常见现代写法:

SELECT FROM ztable AS a
  FIELDS a~field1,
         a~field2,
         a~field3 AS alias_name
  WHERE a~field1 = @lv_value
  ORDER BY a~field1, a~field2
  INTO TABLE @DATA(lt_result)
  UP TO @lv_limit ROWS.

很多系统也常见经典写法:

SELECT field1, field2, field3
  FROM ztable
  WHERE field1 = @lv_value
  INTO TABLE @DATA(lt_result).

4. 读取单行

4.1 按完整键读取:SELECT SINGLE

适合主键或唯一条件明确的读取:

SELECT SINGLE FROM mara
  FIELDS matnr, mtart, matkl
  WHERE matnr = @lv_matnr
  INTO @DATA(ls_mara).

4.2 按排序取第一条:UP TO 1 ROWS

如果条件会命中多条,且你要“按某规则第一条”,用 ORDER BY ... UP TO 1 ROWS

SELECT FROM vbak
  FIELDS vbeln, erdat, ernam
  WHERE kunnr = @lv_kunnr
  ORDER BY erdat DESCENDING, vbeln DESCENDING
  INTO TABLE @DATA(lt_latest)
  UP TO 1 ROWS.

READ TABLE lt_latest INTO DATA(ls_latest) INDEX 1.

要点:

  • SELECT SINGLE 更像“找一条已被唯一条件确定的行”。
  • UP TO 1 ROWS 更像“从多条候选中按排序取第一条”。
  • 没有 ORDER BY 时,不要依赖数据库返回顺序。

5. 读取多行

5.1 读入内表

SELECT FROM vbap
  FIELDS vbeln, posnr, matnr, kwmeng
  WHERE vbeln = @lv_vbeln
  INTO TABLE @DATA(lt_vbap).

5.2 追加到已有内表

SELECT FROM vbap
  FIELDS vbeln, posnr, matnr
  WHERE vbeln IN @s_vbeln
  APPENDING TABLE @lt_vbap.

5.3 对应字段赋值

当目标结构字段名和数据库字段名相同,但字段顺序或字段数量不完全一致:

SELECT FROM mara
  FIELDS matnr, mtart, matkl
  WHERE mtart = @lv_mtart
  INTO CORRESPONDING FIELDS OF TABLE @lt_mara.

注意:CORRESPONDING FIELDS 方便但要确认字段名匹配,避免字段没有被赋值而误以为有值。

5.4 循环读取

SELECT FROM sflight
  FIELDS carrid, connid, fldate
  WHERE carrid = @lv_carrid
  INTO @DATA(ls_flight).

  " process ls_flight

ENDSELECT.

大多数业务场景优先读入内表再处理;超大数据量、需要流式处理时再考虑 SELECT ... ENDSELECT

5.5 分包读取

SELECT FROM zbig_table
  FIELDS key1, key2, amount
  WHERE bukrs = @lv_bukrs
  INTO TABLE @DATA(lt_pack)
  PACKAGE SIZE 1000.

  " process lt_pack

ENDSELECT.

适合大批量处理,避免一次性把所有数据放入内存。

6. WHERE 条件

6.1 常用条件

WHERE field = @lv_value
WHERE field <> @lv_value
WHERE field BETWEEN @lv_low AND @lv_high
WHERE field IN @s_field
WHERE field LIKE @lv_pattern
WHERE field IS NULL
WHERE field IS NOT NULL
WHERE field IS INITIAL
WHERE field IS NOT INITIAL

组合条件:

WHERE bukrs = @lv_bukrs
  AND gjahr = @lv_gjahr
  AND ( blart = 'SA' OR blart = 'KR' )

6.2 IN @range

选择屏幕的 SELECT-OPTIONS 可以直接用于 IN

SELECT-OPTIONS s_matnr FOR mara-matnr.

SELECT FROM mara
  FIELDS matnr, mtart
  WHERE matnr IN @s_matnr
  INTO TABLE @DATA(lt_mara).

6.3 LIKE

DATA(lv_pattern) = 'ABC%'.

SELECT FROM mara
  FIELDS matnr, maktx
  WHERE matnr LIKE @lv_pattern
  INTO TABLE @DATA(lt_result).

常见通配符:

  • %:任意长度字符。
  • _:单个字符。

6.4 初始值和空值

ABAP 初始值和数据库 NULL 不是一回事:

WHERE field IS INITIAL
WHERE field IS NULL

常规 SAP 透明表字段通常不是 NULL,但外连接、CDS、SQL 表达式等场景可能产生空值。

7. JOIN

7.1 INNER JOIN

只返回两边都匹配的行:

SELECT FROM vbak AS h
  INNER JOIN vbap AS i
    ON i~vbeln = h~vbeln
  FIELDS h~vbeln,
         h~auart,
         i~posnr,
         i~matnr
  WHERE h~vkorg = @lv_vkorg
  INTO TABLE @DATA(lt_so_items).

7.2 LEFT OUTER JOIN

保留左表行,右表没有匹配时右表字段为空值或初始值:

SELECT FROM vbak AS h
  LEFT OUTER JOIN vbap AS i
    ON i~vbeln = h~vbeln
  FIELDS h~vbeln,
         h~auart,
         i~posnr,
         i~matnr
  WHERE h~vkorg = @lv_vkorg
  INTO TABLE @DATA(lt_result).

注意:如果把右表字段条件写在 WHERE 里,可能让外连接效果接近内连接。右表筛选条件很多时候应放在 ON 里:

SELECT FROM vbak AS h
  LEFT OUTER JOIN vbap AS i
    ON  i~vbeln = h~vbeln
    AND i~matnr = @lv_matnr
  FIELDS h~vbeln, i~posnr, i~matnr
  INTO TABLE @DATA(lt_result).

8. 子查询

8.1 EXISTS

SELECT FROM vbak AS h
  FIELDS h~vbeln, h~kunnr
  WHERE EXISTS (
    SELECT FROM vbap AS i
      FIELDS i~vbeln
      WHERE i~vbeln = h~vbeln
        AND i~matnr = @lv_matnr
  )
  INTO TABLE @DATA(lt_orders).

8.2 IN ( SELECT ... )

SELECT FROM mara
  FIELDS matnr, mtart
  WHERE matnr IN (
    SELECT FROM marc
      FIELDS matnr
      WHERE werks = @lv_werks
  )
  INTO TABLE @DATA(lt_mara).

9. FOR ALL ENTRIES

FOR ALL ENTRIES 常用于“用内表中的键去数据库取明细”:

IF lt_keys IS NOT INITIAL.
  SELECT FROM vbap
    FIELDS vbeln, posnr, matnr
    FOR ALL ENTRIES IN @lt_keys
    WHERE vbeln = @lt_keys-vbeln
    INTO TABLE @DATA(lt_vbap).
ENDIF.

必须注意:

  • lt_keys 为空时不要执行,否则可能读取全表。
  • 先删除驱动内表重复键,减少数据库负担。
  • 条件尽量覆盖足够字段,避免取回过多数据。
  • 新系统可以优先考虑 JOININ @range、或内表作为数据源。

去重示例:

SORT lt_keys BY vbeln.
DELETE ADJACENT DUPLICATES FROM lt_keys COMPARING vbeln.

10. 内表作为数据源

较新 ABAP 版本支持在 SELECT 中把内表作为数据源,适合替代部分 FOR ALL ENTRIES

SELECT FROM @lt_keys AS k
  INNER JOIN vbap AS i
    ON i~vbeln = k~vbeln
  FIELDS i~vbeln, i~posnr, i~matnr
  INTO TABLE @DATA(lt_vbap).

注意:该能力依赖系统版本;大内表可能被传到数据库侧,应结合数据量和执行计划评估。

11. 聚合与分组

11.1 常用聚合函数

SELECT FROM vbap
  FIELDS vbeln,
         COUNT( * ) AS item_count,
         SUM( kwmeng ) AS total_qty,
         MIN( posnr ) AS first_posnr,
         MAX( posnr ) AS last_posnr
  WHERE vbeln IN @s_vbeln
  GROUP BY vbeln
  INTO TABLE @DATA(lt_summary).

常用聚合:

  • COUNT( * )
  • COUNT( DISTINCT field )
  • SUM( field )
  • AVG( field )
  • MIN( field )
  • MAX( field )

11.2 HAVING

WHERE 过滤明细行,HAVING 过滤分组后的结果:

SELECT FROM vbap
  FIELDS vbeln, SUM( kwmeng ) AS total_qty
  GROUP BY vbeln
  HAVING SUM( kwmeng ) > @lv_min_qty
  INTO TABLE @DATA(lt_result).

12. 排序与分页

12.1 ORDER BY

SELECT FROM vbak
  FIELDS vbeln, erdat, ernam
  WHERE erdat BETWEEN @lv_from AND @lv_to
  ORDER BY erdat DESCENDING, vbeln ASCENDING
  INTO TABLE @DATA(lt_orders).

常见写法:

ORDER BY PRIMARY KEY
ORDER BY field1 ASCENDING, field2 DESCENDING

要点:

  • 不写 ORDER BY 就不要假设返回顺序。
  • 分页、取最新、取最早等场景必须显式排序。

12.2 UP TO n ROWS

SELECT FROM mara
  FIELDS matnr, mtart
  WHERE mtart = @lv_mtart
  INTO TABLE @DATA(lt_mara)
  UP TO 100 ROWS.

12.3 OFFSET

SELECT FROM ztable
  FIELDS key1, text1
  WHERE status = @lv_status
  ORDER BY key1
  INTO TABLE @DATA(lt_page)
  UP TO @lv_page_size ROWS
  OFFSET @lv_offset.

要点:

  • 使用 OFFSET 时需要稳定排序。
  • ORDER BY 字段最好能唯一确定顺序,否则分页可能跳行或重复。

13. SQL 表达式

13.1 字段别名

SELECT FROM mara
  FIELDS matnr AS material,
         mtart AS material_type
  INTO TABLE @DATA(lt_result).

13.2 CASE

SELECT FROM vbak
  FIELDS vbeln,
         CASE auart
           WHEN 'OR' THEN 'Standard Order'
           WHEN 'RE' THEN 'Return'
           ELSE 'Other'
         END AS order_type_text
  INTO TABLE @DATA(lt_orders).

13.3 COALESCE

SELECT FROM ztable
  FIELDS key1,
         coalesce( optional_text, fallback_text ) AS display_text
  INTO TABLE @DATA(lt_result).

13.4 CAST

SELECT FROM ztable
  FIELDS key1,
         CAST( amount AS DEC( 15, 2 ) ) AS amount_dec
  INTO TABLE @DATA(lt_result).

13.5 算术表达式

SELECT FROM vbap
  FIELDS vbeln,
         posnr,
         kwmeng * netpr AS gross_value
  INTO TABLE @DATA(lt_result).

14. DISTINCT

SELECT FROM vbap
  FIELDS DISTINCT matnr
  WHERE werks = @lv_werks
  INTO TABLE @DATA(lt_matnr).

适合去重,但不要把它当成修复重复数据逻辑的万能手段。能从业务键上明确唯一性时,优先明确业务键。

15. CTE:WITH

Common Table Expression 适合把复杂查询拆成可读的临时结果:

WITH
  +orders AS (
    SELECT FROM vbak
      FIELDS vbeln, kunnr, erdat
      WHERE erdat >= @lv_from_date
  ),
  +items AS (
    SELECT FROM vbap
      FIELDS vbeln, posnr, matnr
  )
SELECT FROM +orders AS h
  INNER JOIN +items AS i
    ON i~vbeln = h~vbeln
  FIELDS h~vbeln, h~kunnr, i~posnr, i~matnr
  INTO TABLE @DATA(lt_result).

CTE 名称通常以 + 开头。

16. 集合操作

较新 ABAP SQL 支持集合操作,具体以系统版本为准:

SELECT FROM ztable_a
  FIELDS key1, text1
  WHERE status = 'A'
UNION ALL
SELECT FROM ztable_b
  FIELDS key1, text1
  WHERE status = 'A'
INTO TABLE @DATA(lt_union).

常见集合操作:

  • UNION:合并并去重。
  • UNION ALL:合并但保留重复。
  • INTERSECT:交集。
  • EXCEPT:差集。

17. 动态 Open SQL

17.1 动态表名

DATA(lv_tabname) = 'MARA'.

SELECT FROM (lv_tabname)
  FIELDS *
  INTO TABLE @DATA(lt_data)
  UP TO 10 ROWS.

17.2 动态字段

DATA lt_fields TYPE STANDARD TABLE OF string WITH EMPTY KEY.
lt_fields = VALUE #( ( `MATNR` ) ( `MTART` ) ).

TYPES: BEGIN OF ty_mara_sel,
         matnr TYPE mara-matnr,
         mtart TYPE mara-mtart,
       END OF ty_mara_sel.

DATA lt_result TYPE STANDARD TABLE OF ty_mara_sel WITH EMPTY KEY.

SELECT (lt_fields)
  FROM mara
  INTO TABLE @lt_result
  UP TO 10 ROWS.

17.3 动态条件

DATA(lv_where) = `MTART = 'FERT'`.

SELECT FROM mara
  FIELDS matnr, mtart
  WHERE (lv_where)
  INTO TABLE @DATA(lt_mara).

注意:

  • 动态 SQL 要做白名单校验。
  • 不要直接拼接未校验的用户输入。
  • 能用静态 SQL 和 @ 主机变量时,优先用静态写法。

18. INSERT

18.1 插入单行

DATA ls_ztab TYPE ztable.

ls_ztab-key1 = lv_key1.
ls_ztab-text1 = lv_text.

INSERT ztable FROM @ls_ztab.

IF sy-subrc = 0.
  " inserted
ENDIF.

18.2 插入多行

INSERT ztable FROM TABLE @lt_ztab.

DATA(lv_inserted) = sy-dbcnt.

18.3 接受重复键

INSERT ztable FROM TABLE @lt_ztab ACCEPTING DUPLICATE KEYS.

DATA(lv_inserted) = sy-dbcnt.

适合批量插入时跳过已存在记录,但需要用 sy-dbcnt 判断实际插入数量。

19. UPDATE

19.1 按条件更新

UPDATE ztable
  SET status = @lv_status,
      changed_by = @sy-uname,
      changed_on = @sy-datum
  WHERE key1 = @lv_key1.

DATA(lv_updated) = sy-dbcnt.

19.2 按工作区更新

UPDATE ztable FROM @ls_ztab.

按工作区更新时,数据库行通常由主键字段定位;要确认工作区中的键字段完整且正确。

19.3 批量更新

UPDATE ztable FROM TABLE @lt_ztab.

DATA(lv_updated) = sy-dbcnt.

20. MODIFY

MODIFY dbtab 对数据库表是“按主键存在则更新,不存在则插入”的 upsert 式操作:

MODIFY ztable FROM @ls_ztab.
MODIFY ztable FROM TABLE @lt_ztab.

注意:

  • 需要明确区分“新增”和“修改”时,不要无脑使用 MODIFY
  • 如果业务要求重复时报错,应使用 INSERT 并检查结果。
  • 如果业务要求不存在时报错,应使用 UPDATE 并检查 sy-dbcnt

21. DELETE

21.1 按条件删除

DELETE FROM ztable
  WHERE key1 = @lv_key1
    AND status = @lv_status.

DATA(lv_deleted) = sy-dbcnt.

21.2 按工作区删除

DELETE ztable FROM @ls_ztab.

21.3 批量删除

DELETE ztable FROM TABLE @lt_ztab.

DATA(lv_deleted) = sy-dbcnt.

注意:DELETE FROM ztable. 没有 WHERE 会删除整张表数据,开发和生产都要极其谨慎。

22. 事务、提交与回滚

Open SQL 写操作属于 SAP LUW:

INSERT ztable FROM TABLE @lt_data.

IF sy-subrc = 0.
  COMMIT WORK.
ELSE.
  ROLLBACK WORK.
ENDIF.

实践建议:

  • 报表或自定义批处理可以在明确边界处 COMMIT WORK
  • BAdI、User Exit、增强点、更新任务等框架内,通常不要随意提交,由外层业务流程控制事务。
  • 多表更新要设计一致性:任一关键步骤失败时应回滚或补偿。

23. 锁

Open SQL 的 UPDATE/DELETE 不等于 SAP 业务锁。需要业务并发控制时,优先使用锁对象:

CALL FUNCTION 'ENQUEUE_EZ_MY_LOCK'
  EXPORTING
    key1 = lv_key1.

" Open SQL update/delete

CALL FUNCTION 'DEQUEUE_EZ_MY_LOCK'
  EXPORTING
    key1 = lv_key1.

实践建议:

  • 修改业务主数据、凭证、配置表前先确认是否已有标准锁对象。
  • 不要只靠“先 SELECT 再 UPDATE”来防并发覆盖。
  • 需要防止覆盖时,可在 WHERE 中加入版本号、时间戳或旧值条件。

24. 常用业务模板

24.1 判断是否存在

SELECT FROM ztable
  FIELDS key1
  WHERE key1 = @lv_key1
  INTO @DATA(lv_dummy)
  UP TO 1 ROWS.
ENDSELECT.

IF sy-subrc = 0.
  " exists
ENDIF.

如果是完整主键,也可以:

SELECT SINGLE FROM ztable
  FIELDS key1
  WHERE key1 = @lv_key1
  INTO @DATA(lv_key_found).

24.2 查主表和明细

SELECT FROM vbak AS h
  INNER JOIN vbap AS i
    ON i~vbeln = h~vbeln
  FIELDS h~vbeln,
         h~kunnr,
         h~erdat,
         i~posnr,
         i~matnr,
         i~kwmeng
  WHERE h~vbeln IN @s_vbeln
  INTO TABLE @DATA(lt_sales).

24.3 批量按键查描述

SORT lt_matnr BY matnr.
DELETE ADJACENT DUPLICATES FROM lt_matnr COMPARING matnr.

IF lt_matnr IS NOT INITIAL.
  SELECT FROM makt
    FIELDS matnr, maktx
    FOR ALL ENTRIES IN @lt_matnr
    WHERE matnr = @lt_matnr-matnr
      AND spras = @sy-langu
    INTO TABLE @DATA(lt_makt).
ENDIF.

24.4 批量更新状态

UPDATE ztable
  SET status = @gc_status_done,
      changed_by = @sy-uname,
      changed_on = @sy-datum
  WHERE run_id = @lv_run_id
    AND status = @gc_status_open.

DATA(lv_updated) = sy-dbcnt.

24.5 安全 upsert

SELECT SINGLE FROM ztable
  FIELDS key1
  WHERE key1 = @ls_data-key1
  INTO @DATA(lv_existing_key).

IF sy-subrc = 0.
  UPDATE ztable FROM @ls_data.
ELSE.
  INSERT ztable FROM @ls_data.
ENDIF.

如果并发要求高,需要配合锁对象或唯一键异常处理。

25. 性能与可维护性检查清单

  • 尽量不要 SELECT *,只取需要字段。
  • 不要依赖数据库默认排序,需要顺序就写 ORDER BY
  • 避免在 LOOP 中反复 SELECT SINGLE;先收集键,再一次性查询。
  • FOR ALL ENTRIES 前必须判断内表非空,并尽量去重。
  • 条件尽量使用索引字段或主键字段。
  • 大批量处理用 PACKAGE SIZE 或按键分页。
  • 聚合、过滤、排序尽量让数据库完成,不要全量取回 ABAP 再处理。
  • 写操作后检查 sy-subrcsy-dbcnt
  • 多表写入要考虑事务边界、锁和失败回滚。
  • 动态 SQL 必须做白名单校验。
  • 外连接右表条件的位置要谨慎,确认写在 ON 还是 WHERE
  • 分页使用稳定且尽量唯一的排序字段。

26. 新旧写法对照

26.1 旧式工作区

DATA: ls_mara TYPE mara,
      lt_mara TYPE TABLE OF mara.

SELECT matnr mtart matkl
  FROM mara
  INTO CORRESPONDING FIELDS OF TABLE lt_mara
  WHERE mtart = lv_mtart.

26.2 现代写法

SELECT FROM mara
  FIELDS matnr, mtart, matkl
  WHERE mtart = @lv_mtart
  INTO TABLE @DATA(lt_mara).

26.3 旧式变量混写

SELECT SINGLE matnr mtart
  FROM mara
  INTO ls_mara
  WHERE matnr = lv_matnr.

26.4 现代写法

SELECT SINGLE FROM mara
  FIELDS matnr, mtart
  WHERE matnr = @lv_matnr
  INTO @DATA(ls_mara).

27. 常见坑

27.1 FOR ALL ENTRIES 驱动表为空

错误风险:

SELECT FROM vbap
  FIELDS vbeln, posnr
  FOR ALL ENTRIES IN @lt_keys
  WHERE vbeln = @lt_keys-vbeln
  INTO TABLE @DATA(lt_vbap).

正确习惯:

IF lt_keys IS NOT INITIAL.
  SELECT FROM vbap
    FIELDS vbeln, posnr
    FOR ALL ENTRIES IN @lt_keys
    WHERE vbeln = @lt_keys-vbeln
    INTO TABLE @DATA(lt_vbap).
ENDIF.

27.2 UP TO 1 ROWS 没有排序

SELECT FROM vbak
  FIELDS vbeln, erdat
  WHERE kunnr = @lv_kunnr
  INTO TABLE @DATA(lt_one)
  UP TO 1 ROWS.

这不是“最新一条”,只是不确定的一条。要写:

SELECT FROM vbak
  FIELDS vbeln, erdat
  WHERE kunnr = @lv_kunnr
  ORDER BY erdat DESCENDING, vbeln DESCENDING
  INTO TABLE @DATA(lt_one)
  UP TO 1 ROWS.

27.3 LEFT JOIN 右表条件写错位置

可能破坏外连接语义:

SELECT FROM zhead AS h
  LEFT OUTER JOIN zitem AS i
    ON i~docno = h~docno
  FIELDS h~docno, i~itemno
  WHERE i~status = 'A'
  INTO TABLE @DATA(lt_result).

通常应考虑:

SELECT FROM zhead AS h
  LEFT OUTER JOIN zitem AS i
    ON  i~docno = h~docno
    AND i~status = 'A'
  FIELDS h~docno, i~itemno
  INTO TABLE @DATA(lt_result).

27.4 MODIFY 掩盖业务语义

MODIFY 很方便,但它会模糊“应该新增”还是“应该修改”。接口、财务、库存等关键逻辑中,建议明确使用 INSERTUPDATE 并检查结果。

28. 官方参考

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
MCP自动发表文章
评论列表

发表评论

评论内容
昵称:
验证码:
验证码
关联文章

ABAP Open SQL 语法整理SELECTJOIN增删常见
ABAP 基础语法教程:运算、字符串、判断循环
ABAP AT SELECTION-SCREEN 事件详解:选择屏幕校验动态处理
ABAP基础语法:变量、系统变量、数据类型结构体变量详解
DBHelper SqlSugar EntityFramework 增删查 性能对比测试
C#的进化——C#发展史、C#1.0-10.0语法系统性梳理、C#JAVA的对比
ABAP 数据字典 DDIC 详解:从 Domain 到透明表、搜索帮助锁对象
Elasticsearch使用系列-ES增删基本操作+ik分词
ABAP 内表三种类型对比:STANDARD、SORTED HASHED TABLE 如何选择
window server部署open VPN
ABAP 报表选择屏幕常用语句详解
如何在 SQL Server 中按照修改时间排序获取最新更的表和存储过程
Linq to SQL语句基础讲解
C#常见异常列表
SAP ABAP 数据类型和常量基础
SAP ABAP 开发常用事务码核心概念:SE37、SE38、SE80、增强技术及 ALE/EDI/IDoc
Xamarin.Android 踩
less里面calc() 语法使用
C#数据类型和常见数据库(SQLServer,MySQL,Oracle,SQLite)的数据类型对应关系
数据库为snake_case脚本