ABAP如何实现从两张表按优先级查询单值数据
ABAP双表优先级取数方案解答
原有代码问题
你当前编写的代码逻辑不符合需求:判断条件IF NOT ATEXT is initial是在查询执行前判断变量ATEXT是否为空,并非判断第一张表是否查询到匹配数据,逻辑完全错误。
两个疑问的明确答复
- 先查第一张表、通过
sy-subrc判断未命中再查第二张表的方案完全可行,是ABAP开发中该类场景的标准最优写法,性能开销最小 - 纯SQL实现的话
JOIN不适合该场景,UNION可以实现但性能、兼容性、可读性都不如上面的方案,非特殊场景不推荐
推荐实现代码(sy-subrc判断方案)
sy-subrc是ABAP内置系统字段,每次执行SQL等操作后会自动赋值:SELECT SINGLE执行后返回0代表查询命中,返回4代表未找到匹配数据,参考写法如下(适配ABAP 7.40+版本,目前绝大多数SAP环境都支持):
" 优先查询第一张表 SELECT SINGLE atext FROM tablea WHERE aname = @<你的查询入参> INTO @DATA(lv_target_val). " 第一张表未命中时,查询第二张表兜底 IF sy-subrc <> 0. SELECT SINGLE btext FROM tableb WHERE bname = @<你的查询入参> INTO @lv_target_val. ENDIF. " 可选:如果两张表都可能无数据,此处加空值兜底逻辑
如果你的系统版本低于7.40,提前用DATA语句定义lv_target_val变量即可,逻辑完全一致。
JOIN/UNION实现的相关说明
为什么不推荐JOIN
JOIN的作用是按关联条件拼接两张表的行数据,如果用左连接以tablea为主表关联tableb,会出现两表同时命中时返回冗余数据的问题,需要额外处理去重和优先级,关联条件写错还容易触发笛卡尔积,性能差、逻辑冗余,完全不适合该场景。
UNION实现方式(不推荐常规使用)
UNION可以合并两个查询的结果集,通过自定义优先级排序取第一条就能实现需求,参考写法:
SELECT SINGLE val FROM ( SELECT atext AS val, 1 AS sort_priority FROM tablea WHERE aname = @<查询入参> UNION ALL SELECT btext AS val, 2 AS sort_priority FROM tableb WHERE bname = @<查询入参> ) AS tmp_result ORDER BY sort_priority ASCENDING INTO @DATA(lv_target_val_union).
该写法的问题:
- 无论第一张表是否命中,都会扫描两张表的数据,性能比优先查第一张表的方案差
- 子查询+UNION的写法在部分老版本SAP系统中不支持,兼容性差
- 代码可读性低,后续维护成本高
只有在必须单条SQL实现的特殊场景下才考虑使用。
内容的提问来源于stack exchange,提问作者ValdeCTN
相关产品推荐
相关产品推荐

