ABAP New Syntax - Read Table, Table Expressions

정준환·2024년 2월 3일
1

이번 포스팅에서는 Standard Table에 대해서만 다룰 예정이다. READ TABLE을 대체할 수 있는 신 문법, Table Expressions 에 대해 소개한다.

0. Type 및 Data 정의

TYPES: BEGIN OF structure_type,
         col1 TYPE type1,
         col2 TYPE type2,
         col3 TYPE type3,
       END OF structure_type,
       
       table_type TYPE STANDARD TABLE OF structure_type.
       
DATA: itab TYPE table_type.

1. 데이터 읽는 방법 - Index

" Old
READ TABLE itab INDEX 1 INTO DATA(wa).

" New
DATA(wa) = itab[ 1 ].

다만, 위처럼 사용하면 해당 index에 맞는 data가 존재하지 않을 때, ITAB_LINE_NOT_FOUND Error가 발생한다. 이를 TRY-CATCH를 이용해 해결해보면 방법은 아래와 같다.

TRY
    DATA(wa) = itab[ 1 ].
  CATCH cx_sy_itab_line_not_found.
ENDTRY.

하지만 매번 이렇게 사용하면 오히려 불편하다. 따라서 이런 상황에서는 아래처럼 VALUEOPTIONAL을 이용하여 감싸주어 해당 문제를 해결한다. 데이터가 존재한다는 확신이 없는 상황에서는 항상 써준다고 생각하면 좋을 것 같다.

DATA(wa) = VALUE #( itab[ 1 ] OPTIONAL ).

당연히 이렇게 특정 Field의 값만 가져오는 것도 가능하다.

DATA(val1) = VALUE #( itab[ 1 ]-col1 OPTIONAL ).

2. 데이터 읽는 방법 - Key

위와 마찬가지로, ITAB_LINE_NOT_FOUND Error를 피하기 위해 VALUEOPTIONAL을 이용하여 감싸주는 것이 좋다.

" Old
READ TABLE itab WITH KEY col1 = 'VAL1' INTO DATA(wa).

" New
DATA(wa) = itab[ col1 = 'VAL1' ].
DATA(wa) = VALUE #( itab[ col1 = 'VAL1' ] OPTIONAL ).

조건을 여러가지 주고 싶은 경우엔 여러개를 써주면 된다.

" Old
READ TABLE itab WITH KEY col1 = 'VAL1' 
                         col2 = 'VAL2' INTO DATA(wa).

" New
DATA(wa) = VALUE #( itab[ col1 = 'VAL1'
                          col2 = 'VAL2' ] OPTIONAL ).

3. 데이터 읽는 방법 - Binary Search (Secondary Key)

일반적으로 Binary Search는 아래와 같이 진행한다.

SORT itab BY col1.
READ TABLE itab WITH KEY col1 = 'VAL1' BINARY SEARCH INTO DATA(wa).

안타깝게도 New Syntax에서는 이러한 형태의 Binary Search를 지원하지 않는다. 대신 Secondary Key를 사용해야한다. 아래 글을 보면 Secondary Key를 사용하는 것이 일반적으로 더 빠른 것 또한 알 수 있다.
SAP ABAP Technical Help: Performance READ TABLE with Secondary Table Key Vs Binary Search

이를 위해 Table을 다시 정의한다.

TYPES: table_type_secondary_key TYPE STANDARD TABLE OF structure_type
                                WITH NON-UNIQUE SORTED KEY key_1 COMPONENTS col1.

DATA: itab_secondary_key TYPE table_type_secondary_key.

이제 이를 이용해 Table을 읽을 수 있다. Secondary Key를 활용했기 때문에 추가적인 SORT 등을 수행 할 필요가 없다.

" Old
READ TABLE itab_secondary_key WITH TABLE KEY key_1 COMPONENTS col1 = 'VAL1' INTO DATA(wa).

" New
DATA(wa) = VALUE #( itab_secondary_key[ KEY key_1 col1 = 'VAL1' ] OPTIONAL ).

4. 응용

아래는 Table Expressions를 사용하는 예시들이다.

4-1. Field Symbol Assign

" Old
READ TABLE itab INDEX 1 ASSIGNING FIELD-SYMBOL(<fs>).
IF sy-subrc = 0.
  ...
ENDIF.

" New
ASSIGN itab[ 1 ] TO FIELD-SYMBOL(<fs>) ELSE UNASSIGN.
IF <fs> IS ASSIGN.
  ...
ENDIF.

4-2. 데이터 존재 확인

" Old
READ TABLE itab WITH KEY col1 = 'VAL1' TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
  ...
ENDIF.

" New
IF line_exists( itab[ col1 = 'VAL1' ] ).
  ...
ENDIF.

4-3. Index 가져오기

"Old
READ TABLE itab WITH KEY col1 = 'VAL1' TRANSPORTING NO FIELDS
DATA(idx) = sy-tabix.

" New
DATA(idx) = line_index( itab[ col1 = 'VAL1' ] ).

데이터가 없는 경우는 0을 반환한다. 또한 Index가 존재할 수 없는 Hashed Table이나 Hashed Secondary Key를 사용한 경우에는 -1을 반환한다.

4-4. Table 데이터 변경

" Old
READ TABLE itab WITH KEY col1 = 'VAL1' ASSIGNING FIELD-SYMBOL(<fs>).
<fs>-col1 = 'VAL4'.

" New
itab[ col1 = 'VAL1' ]-col1 = 'VAL4'.

다만 앞서 설명했듯, 해당 구문은 ITAB_LINE_NOT_FOUND 가 발생할 수 있다. 이를 위해, 데이터가 존재하지 않을 수 있는 경우에는 아래처럼 사용한다. 다른 간단한 방법이 있는지는 잘 모르겠다.

" Old
READ TABLE itab WITH KEY col1 = 'VAL1' ASSIGNING FIELD-SYMBOL(<fs>).
IF sy-subrc = 0.
  <fs>-col1 = 'VAL4'.
ENDIF.

" New
DATA(idx) = line_index( itab[ col1 = 'VAL1' ] ).
IF idx > 0.
  itab[ idx ]-col1 = 'VAL4'.
ENDIF.

물론 아래처럼 직접적으로 TRY-CATCH를 사용할 수도 있겠지만, SAP에서 권장하는 방법인지는 잘 모르겠다.

TRY.
    itab[ col1 = 'VAL1' ]-col1 = 'VAL4'.
  CATCH cx_sy_itab_line_not_found.
ENTRY.

4-5. Chainings

Table안에 또 Table이 있고, 또 있고,,, 이런식으로 Nested 구조의 Table을 간단하게 접근할 수 있다. 대표적으로 ALV의 경우 lvc_t_scol과 같은 table을 요구하는 경우가 많다. 이런 경우 Table Expressions가 굉장히 유용하게 활용될 수 있는데, 예시를 위해 아래 Type을 다시 지정한다.

TYPES: BEGIN OF nested_structure_type,
         col4        TYPE type4,
         inner_table TYPE table_type,
       END OF nested_structure_type,
       
       nested_table_type TYPE STANDARD TABLE OF nested_structure_type.
       
DATA: nested_itab TYPE nested_table_type.

이제 해당 table을 가지고 Table Expressions를 적용해보자. 편의를 위해 sy-subrc, ITAB_LINE_NOT_FOUND 등을 체크하는 로직은 생략했다.

" Old
READ TABLE nested_itab      WITH KEY col4 = 'VAL4' ASSIGNING FIELD-SYMBOL(<fs>).
READ TABLE <fs>-inner_table WITH KEY col1 = 'VAL1' ASSIGNING FIELD-SYMBOL(<fs_inner>).
<fs_inner>-col2 = 'VAL2'.

" New
nested_itab[ col4 = 'VAL4' ]-inner_table[ col1 = 'VAL1' ]-col2 = 'VAL2'.

감사합니다.

profile
정준환

1개의 댓글

comment-user-thumbnail
2024년 12월 3일

잘봤습니다 ^^

답글 달기