如何检查ADRC表中同时存在两个指定的有效地址编号?
如何检查ADRC表中同时存在两个指定的有效地址编号?
看你的描述,问题出在原来用OR查询两个地址时,只要其中一个地址有效存在,结果内表就不为空,导致你没法正确判断「两个地址是否都满足有效存在的条件」。咱们可以把逻辑拆开来,逐个检查每个非空的地址编号,这样就能精准控制判断逻辑了。
先明确你的核心需求:当addrnum_dd和addrnum_pbd都不为空时,必须两个地址都在ADRC表中,且都处于有效期内(date_from ≤ 当前日期且date_to ≥ 当前日期),才标记检查通过(lv_chk为空);只要其中一个地址不存在或过期,就把lv_chk设为X(abap_true)。
下面给你两种实现方式,都符合你要求的「对每个非空字段做检查」的需求:
方式一:逐个查询数据库(性能友好)
这种方式针对每个非空地址编号单独做SELECT SINGLE查询,避免一次性拉取不必要的数据,适合数据量较大的场景:
SELECT SINGLE addrnum_dd addrnum_pbd INTO (lv_addrnum_dd, lv_addrnum_pbd) FROM zfsltcase_agr WHERE case_guid = iv_case_guid. IF sy-subrc = 0. lv_chk = abap_false. " 默认设为检查通过,只要有一个地址不满足就改为X " 检查第一个地址编号 addrnum_dd IF lv_addrnum_dd IS NOT INITIAL. SELECT SINGLE addrnumber FROM adrc WHERE addrnumber = lv_addrnum_dd AND date_from <= sy-datum AND date_to >= sy-datum. IF sy-subrc <> 0. " 地址不存在或已过期 lv_chk = abap_true. ENDIF. ENDIF. " 检查第二个地址编号 addrnum_pbd,可加优化:如果第一个已经不满足,就不用查第二个了 IF lv_addrnum_pbd IS NOT INITIAL AND lv_chk = abap_false. SELECT SINGLE addrnumber FROM adrc WHERE addrnumber = lv_addrnum_pbd AND date_from <= sy-datum AND date_to >= sy-datum. IF sy-subrc <> 0. lv_chk = abap_true. ENDIF. ENDIF. " 补充:如果只有一个地址非空,检查该地址是否有效(按需保留) IF (lv_addrnum_dd IS NOT INITIAL XOR lv_addrnum_pbd IS NOT INITIAL) AND lv_chk = abap_false. DATA(lv_single_addr) = COND #( WHEN lv_addrnum_dd IS NOT INITIAL THEN lv_addrnum_dd ELSE lv_addrnum_pbd ). SELECT SINGLE addrnumber FROM adrc WHERE addrnumber = lv_single_addr AND date_from <= sy-datum AND date_to >= sy-datum. IF sy-subrc <> 0. lv_chk = abap_true. ENDIF. ENDIF. ELSE. " 未查到合同记录时的默认处理,可按需调整 lv_chk = abap_false. ENDIF.
方式二:先拉取内表再做READ TABLE检查
这种方式先把两个地址的有效记录一次性拉到内表,再通过READ TABLE逐个判断是否存在,符合你提到的「read table check」要求:
SELECT SINGLE addrnum_dd addrnum_pbd INTO (lv_addrnum_dd, lv_addrnum_pbd) FROM zfsltcase_agr WHERE case_guid = iv_case_guid. IF sy-subrc = 0. lv_chk = abap_false. " 先拉取两个地址编号对应的所有有效记录 SELECT addrnumber INTO TABLE lt_addr FROM adrc WHERE (addrnumber = lv_addrnum_dd OR addrnumber = lv_addrnum_pbd) AND date_from <= sy-datum AND date_to >= sy-datum. " 检查addrnum_dd是否在有效记录内 IF lv_addrnum_dd IS NOT INITIAL. READ TABLE lt_addr WITH KEY addrnumber = lv_addrnum_dd TRANSPORTING NO FIELDS. IF sy-subrc <> 0. lv_chk = abap_true. ENDIF. ENDIF. " 检查addrnum_pbd是否在有效记录内,同样可加优化逻辑 IF lv_addrnum_pbd IS NOT INITIAL AND lv_chk = abap_false. READ TABLE lt_addr WITH KEY addrnumber = lv_addrnum_pbd TRANSPORTING NO FIELDS. IF sy-subrc <> 0. lv_chk = abap_true. ENDIF. ENDIF. " 补充单个地址非空的检查逻辑(按需保留) IF (lv_addrnum_dd IS NOT INITIAL XOR lv_addrnum_pbd IS NOT INITIAL) AND lv_chk = abap_false. DATA(lv_single_addr) = COND #( WHEN lv_addrnum_dd IS NOT INITIAL THEN lv_addrnum_dd ELSE lv_addrnum_pbd ). READ TABLE lt_addr WITH KEY addrnumber = lv_single_addr TRANSPORTING NO FIELDS. IF sy-subrc <> 0. lv_chk = abap_true. ENDIF. ENDIF. ELSE. lv_chk = abap_false. ENDIF.
两种方式的核心逻辑都是逐个验证每个非空地址的有效性,解决了原来用OR查询导致的判断不精准问题。你可以根据实际场景选择:如果数据库访问性能敏感,选方式一;如果需要多次复用内表数据,选方式二。
备注:内容来源于stack exchange,提问作者Alexander Chebotarev
相关产品推荐
相关产品推荐

