I am baffled. If I compile the following piece of code
REPORT zzy.
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
class_constructor,
main.
PRIVATE SECTION.
TYPES: BEGIN OF t_record,
transid TYPE sy-index,
item1 TYPE char20,
value1 TYPE p LENGTH 7 DECIMALS 2,
value2 TYPE p LENGTH 7 DECIMALS 2,
value3 TYPE p LENGTH 7 DECIMALS 2,
value4 TYPE p LENGTH 7 DECIMALS 2,
END OF t_record,
tt_record TYPE STANDARD TABLE OF t_record WITH NON-UNIQUE KEY transid item1 WITH UNIQUE HASHED KEY sec_key COMPONENTS value1 value2 value3.
CLASS-DATA:
mt_record TYPE tt_record.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD class_constructor.
DO 10 TIMES.
INSERT VALUE t_record( transid = sy-index item1 = |Item{ sy-index }| value1 = sy-index value2 = sy-index / 2 value3 = sy-index / 4 value4 = 0 )
INTO TABLE mt_record.
ENDDO.
ENDMETHOD.
METHOD main.
DATA:
l_secs TYPE i,
l_millisecs TYPE i,
l_start TYPE timestampl,
l_end TYPE timestampl,
l_diff LIKE l_start.
GET TIME STAMP FIELD l_start.
LOOP AT mt_record INTO DATA(ls_record)
WHERE value1 = '100.00' AND value2 = '150.0' AND value3 = '10.0'.
ASSERT 1 = 1.
ENDLOOP.
GET TIME STAMP FIELD l_end.
l_diff = l_end - l_start.
WRITE: / l_diff.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
lcl_main=>main( ).
I get the following warning
Program ZZY
Secondary key "SEC_KEY" is completely specified. However, the primary
key is used for access. Check whether access using "SEC_KEY" is more
efficient
but if I specify this key with USING KEY sec_key
then I get a compilation time error!
REPORT zzy.
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
class_constructor,
main.
PRIVATE SECTION.
TYPES: BEGIN OF t_record,
transid TYPE sy-index,
item1 TYPE char20,
value1 TYPE p LENGTH 7 DECIMALS 2,
value2 TYPE p LENGTH 7 DECIMALS 2,
value3 TYPE p LENGTH 7 DECIMALS 2,
value4 TYPE p LENGTH 7 DECIMALS 2,
END OF t_record,
tt_record TYPE STANDARD TABLE OF t_record WITH NON-UNIQUE KEY transid item1 WITH UNIQUE HASHED KEY sec_key COMPONENTS value1 value2 value3.
CLASS-DATA:
mt_record TYPE tt_record.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD class_constructor.
DO 10 TIMES.
INSERT VALUE t_record( transid = sy-index item1 = |Item{ sy-index }| value1 = sy-index value2 = sy-index / 2 value3 = sy-index / 4 value4 = 0 )
INTO TABLE mt_record.
ENDDO.
ENDMETHOD.
METHOD main.
DATA:
l_secs TYPE i,
l_millisecs TYPE i,
l_start TYPE timestampl,
l_end TYPE timestampl,
l_diff LIKE l_start.
GET TIME STAMP FIELD l_start.
LOOP AT mt_record INTO DATA(ls_record) USING KEY sec_key
WHERE value1 = '100.00' AND value2 = '150.0' AND value3 = '10.0'.
ASSERT 1 = 1.
ENDLOOP.
GET TIME STAMP FIELD l_end.
l_diff = l_end - l_start.
WRITE: / l_diff.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
lcl_main=>main( ).
Program ZZY
Key "SEC_KEY" is a secondary key of type "HASHED KEY". All key components must be provided in these cases
What am I doing wrong here?
As stated in the syntax documentation of the LOOP
conditions,
If a secondary table key is specified, any WHERE condition also specified must be optimizable. Otherwise a syntax error occurs or an exception is raised.
Be sure to have a sufficient supply of coffee or whatever stimulants you prefer at hand when diving into the rules of what is comparable and optimizable and what not, because that's tedious stuff. In this case, the comparison specified has to include a TYPE P
and a TYPE C
(like '100.00'
) - which should be possible - but additionally, the lengths have to match, which they don't. Even the documentation states that
Due to the complexity of the comparison rules (particularly for elementary data types, it is not a good idea to construct a set of rules detailing exactly when the comparison type matches the data type of the left operand.
Bottom line: Use the exact same type for key access, never rely on implicit conversions. If you declare a variable or constant using the same type you used for your valueN
columns and use that in the comparison, it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With