READ TABLE with dynamic key fields?
Asked Answered
P

3

5

I have the name of a table DATA lv_tablename TYPE tabname VALUE 'xxxxx', and a generic FIELD-SYMBOLS: <lt_table> TYPE ANY TABLE. which contains entries selected from that corresponding table.

I've defined my line structure FIELD-SYMBOLS: <ls_line> TYPE ANY. which i'd use for reading from the table.

Is there a way to create a READ statement on <lt_table> fully specifying the key fields?

I am aware of the statement / addition READ TABLE xxxx WITH KEY (lv_field_name) = 'asdf'., but this however wouldn't work (afaik) for a dynamic number of key fields, and I wouldn't like to create a large number of READ TABLE statements with an increasing number of key field specifications.

Can this be done?

Pejsach answered 18/9, 2013 at 9:55 Comment(4)
Please also add the tag "crude" in addition to "crud". :-)Is there any real requirement behind this?Pembrook
no real requirements. Just me trying to see how far the language can be streched.Pejsach
@Pembrook the tag "hypothetical" is quite nice. wasn't aware of it. i'll make sure to use it more (basicaly every time :P )Pejsach
@vlad-ardelean: The hypothetical tag is a meta tag and should not be used, really. I've removed it again.Niveous
P
10

Actually i found this to work

DATA lt_bseg TYPE TABLE OF bseg.
DATA ls_bseg TYPE bseg.
DATA lv_string1 TYPE string.
DATA lv_string2 TYPE string.

lv_string1 = `    `.
lv_string2 = lv_string1.

SELECT whatever FROM wherever INTO TABLE lt_bseg.

READ TABLE lt_bseg INTO ls_bseg
    WITH  KEY ('MANDT') = 800
              ('  ')    = ''
              ('BUKRS') = '0005'
              ('BELNR') = '0100000000'
              ('GJAHR') = 2005
              ('BUZEI') = '002'
              ('')      = ''
              ('     ') = ''
              ('    ') = '         '
              (lv_string1) = '1'
              (lv_string2) = ''.

By using this syntax one can just specify as many key fields as required. If some fields will be empty, then these will just get ignored, even if values are specified for these empty fields.

One must pay attention that using this exact syntax (static definitions), 2 fields with the exact same name (even blank names) will not be allowed.

As shown with the variables lv_string1 and lv_string2, at run-time this is no problem.

And lastly, one can specify the fields in any order (i don't know what performance benefits or penalties one might get while using this syntax)

Pejsach answered 19/9, 2013 at 7:18 Comment(2)
If You want to get all keyfields, You can make use of rtts before, gettingt type of internal table, look, which element it has ( if any ) and check which fields are keys. if those fields are keys, You should add them into a internal table , consisting of two columns, where one is the identified table key column name and the other the corresponding value. Later on You easily can create the read_table key binding-conditions .Motherly
or i could SELECT fieldname FROM dd03l WHERE tablename = 'asdf' AND keyflag = 'x'. If I do it with RTTS, apparently i receive the run time key, which is a collection of all the non-numeric fields - but i don't want to use that key.Pejsach
M
0

There seems to be the possibility ( like a dynamic select statement whith binding and lt_dynwhere ).

Please refer to this post, there was someone, who also asked for the requirement:

http://scn.sap.com/thread/1789520

Motherly answered 18/9, 2013 at 12:44 Comment(1)
I think the link provided exemplifies the statement READ TABLE asdf WITH KEY ('asdf') = 'qwer'. I was already aware of it, but didn't want to use that. Eventually I got it to work by taking advantage of fields fields that that can be empty.Pejsach
M
0

3 ways:

Examples (ASSERT statements are used here to prove that the conditions are true, otherwise the program would fail):

TYPES: BEGIN OF ty_table_line,
         key_name_1 TYPE i,
         key_name_2 TYPE i,
         attr       TYPE c LENGTH 1,
       END OF ty_table_line,
       ty_internal_table TYPE SORTED TABLE OF ty_table_line WITH UNIQUE KEY key_name_1 key_name_2.
DATA(itab) = VALUE ty_internal_table( ( key_name_1 = 1 key_name_2 = 1 attr = 'A' )
                                      ( key_name_1 = 1 key_name_2 = 2 attr = 'B' ) ).
"------------------ READ TABLE
DATA(key_name_1) = 'KEY_NAME_1'.
DATA(key_name_2) = 'KEY_NAME_2'.
READ TABLE itab WITH TABLE KEY
        (key_name_1) = 1
        (key_name_2) = 2
        ASSIGNING FIELD-SYMBOL(<line>).
ASSERT <line> = VALUE ty_table_line( key_name_1 = 1 key_name_2 = 2 attr = 'B' ).

key_name_2 = ''. " ignore this key field
READ TABLE itab WITH TABLE KEY
        (key_name_1) = 1
        (key_name_2) = 2                    "<===  will be ignored
        ASSIGNING FIELD-SYMBOL(<line_2>).
ASSERT <line_2> = VALUE ty_table_line( key_name_1 = 1 key_name_2 = 1 attr = 'A' ).
"------------------ LOOP AT
DATA(where) = 'key_name_1 = 1 and key_name_2 = 1'.
LOOP AT itab ASSIGNING FIELD-SYMBOL(<line_3>)
    WHERE (where).
  EXIT.
ENDLOOP.
ASSERT <line_3> = VALUE ty_table_line( key_name_1 = 1 key_name_2 = 1 attr = 'A' ).
"---------------- SELECT ... FROM @itab
SELECT SINGLE * FROM @itab WHERE (where) INTO @DATA(line_3).
ASSERT line_3 = VALUE ty_table_line( key_name_1 = 1 key_name_2 = 1 attr = 'A' ).
Meshuga answered 28/8, 2022 at 9:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.