Consider, I have GT_KUNNR
internal table like below:
KUNNR | TEXT |
---|---|
123 | demo text |
456 | test inv |
I have second GT_TEXT internal like below:
KUNNR | TEXT | EXPIRED |
---|---|---|
123 | welcome | X |
I am writing the code till now in ABAP as:
LOOP AT GT_KUNNR ASSIGNING FIELD-SYMBOL(<lfs_kunnr>).
READ TABLE GT_TEXT ASSIGNING FIELD-SYMBOL(lfs_text>) WITH KEY kunnr = <lfs_kunnr>-kunnr BINARY SEARCH.
IF sy-subrc EQ 0.
<lfs_kunnr>-text = <lfs_text>-text.
ENDIF.
ENDLOOP.
My question is, how to achieve above using ABAP 7.4 and upwards? My understanding is, constructor expression (VALUE,FOR,REDUCE..) creates a new type, which I don't need (basically, GT_KUNNR
is being updated and can have huge records. So, creating new structure/type and then passing that again to GT_KUNNR
will be a performance bottleneck). So, how to achieve that? Any efficient way?
If you want to do this with a constructor operator, then you can use the CORRESPONDING-operator with a lookup table.
But note that this requires that the linking condition between the two tables (kunnr = kunnr
) uses a table key in the lookup table. That means that the lookup table (in this case gt_text
) has to be a SORTED TABLE
or a HASHED TABLE
with kunnr
as the keyfield, or that it at least has a SECONDARY KEY
that matches the condition.
" Declarations:
TYPES:
BEGIN OF kunnr_struct,
kunnr TYPE kunnr,
text TYPE string,
END OF kunnr_struct,
kunnr_tbl TYPE STANDARD TABLE OF kunnr_struct WITH DEFAULT KEY,
BEGIN OF text_struct,
kunnr TYPE kunnr,
text TYPE string,
expired TYPE abap_bool,
END OF text_struct,
text_tbl TYPE HASHED TABLE OF text_struct WITH UNIQUE KEY kunnr. " <- Important!
" Test data:
DATA(gt_kunnr) = VALUE kunnr_tbl(
( kunnr = '123' text = 'demo text' )
( kunnr = '456' text = 'text inv')
).
DATA(gt_text) = VALUE text_tbl(
( kunnr = '123' text = 'welcome' expired = abap_true )
).
" The actual code you asked for:
gt_kunnr = CORRESPONDING kunnr_tbl(
gt_kunnr FROM gt_text USING kunnr = kunnr ).
My understanding is, constructor expression (VALUE,FOR,REDUCE..) creates a new type, which I don't need (basically, GT_KUNNR is being updated and can have huge records.
This does not create a new type, but according to the documentation I linked above, it does indeed create an interim table with the results in memory. This is unlikely to be a performance problem (the runtime increase would probably be linear at worst), but it could double the memory being used, so it could become a memory problem with very large datasets.
If that is a concern for your use-case, then you can keep using your variant with a loop. If you don't want to use field-symbols, then you can do what many modern ABAP styleguides, like this one from SAP themselves, recommend to use references instead of field-symbols whenever possible. The code from the question using references would look like this:
LOOP AT gt_kunnr REFERENCE INTO DATA(lrs_kunnr).
READ TABLE gt_text REFERENCE INTO DATA(lrs_text) WITH KEY kunnr = lrs_kunnr->kunnr BINARY SEARCH.
IF sy-subrc EQ 0.
lrs_kunnr->text = lrs_text->text.
ENDIF.
ENDLOOP.