목차
1. READ TABLE, LOOP AT 이란?
READ TABLE 문은 내부 테이블에서 특정 조건에 맞는 행을 검색하는 데 사용됩니다.
이 구문을 사용하면 지정된 기준(키 값, 인덱스 번호 등)에 따라 내부 테이블의 데이터를 읽을 수 있으며, 검색된 데이터를 작업 영역(work area) 또는 필드에 할당할 수 있습니다.
READ TABLE은 데이터 조회를 위한 핵심적인 문법 중 하나로, ABAP 프로그램에서 데이터 처리 로직을 구현할 때 널리 사용됩니다.
LOOP AT 구문은 내부 테이블의 데이터를 순회하며 각 행에 대한 처리를 수행할 때 사용됩니다.
이 구문을 활용하면 내부 테이블에 저장된 모든 데이터를 반복 접근하여, 각 행에 대해 특정 로직을 실행할 수 있습니다.
두 구문 모두 내부테이블의 행에 접근하기 위해서 사용합니다.
아래 예제를 보면서 이해해 보도록 하겠습니다.
2. READ TABLE 예제
예제1) INDEX
TYPES: BEGIN OF TY_EMPLOYEE,
NAME TYPE STRING,
ID TYPE I,
JOINING_DATE TYPE D,
END OF TY_EMPLOYEE.
DATA : LS_EMPLOYEE TYPE TY_EMPLOYEE,
LT_EMPLOYEE TYPE TABLE OF TY_EMPLOYEE.
LS_EMPLOYEE-NAME = 'John Doe'.
LS_EMPLOYEE-ID = 1001.
LS_EMPLOYEE-JOINING_DATE = '20200301'.
APPEND LS_EMPLOYEE TO LT_EMPLOYEE.
LS_EMPLOYEE-NAME = 'Jane Doe'.
LS_EMPLOYEE-ID = 2000.
LS_EMPLOYEE-JOINING_DATE = '20200301'.
APPEND LS_EMPLOYEE TO LT_EMPLOYEE.
위와같이 내부 테이블 LT_EMPLOYEE에 2개의 행을 APPEND 합니다.
내부 테이블에 특정 위치에 있는 행에 접근할때는 INDEX 구문을 사용하면 됩니다. 아래는 그 예시입니다.
READ TABLE LT_EMPLOYEE INTO LS_EMPLOYEE INDEX 2.
IF SY-SUBRC = 0.
ENDIF.
READ TABLE다음에 내부테이블이 위치합니다. 검색된 DATA를 담기 위해 INTO절 다음에 구조체가 위치합니다.
그리고 INDEX 명령어를 사용하여 내부 테이블에서 READ할 위치를 지정합니다.
내부 테이블에 해당 위치 DATA가 존재하면 시스템 변수인 SY-SUBRC에 0값이 반환됩니다.
예제2) WITH KEY
READ TABLE LT_EMPLOYEE INTO LS_EMPLOYEE WITH KEY NAME = 'John Doe'.
IF SY-SUBRC = 0.
ENDIF.
INDEX대신 특정 조건으로 READ하고 싶을때 WITH KEY 구문을 사용하면 됩니다.
위 예제는 내부테이블의 NAME필드가 'Jone Doe'인 행을 찾아서 구조체로 반환하게 됩니다.
만약 NAME필드에 'Jone Doe' 값을 가지고 있는 행이 여러개가 존재한다면 가장 처음 행을 반환합니다.
READ TABLE LT_EMPLOYEE INTO LS_EMPLOYEE WITH KEY NAME = 'John Doe'
ID = 1001.
IF SY-SUBRC = 0.
ENDIF.
WITH KEY에 조건을 여러개 줄수도 있습니다.
예제3) BINARY SEARCH
BINARY SEARCH는 READ TABLE 구문과 함께 사용되어, 정렬된 내부 테이블에서 데이터를 효율적으로 검색하는 방법을 제공합니다.
이진 검색 알고리즘을 사용하여 작동하기 때문에 BINARY SEARCH 옵션을 사용할 때는 내부 테이블이 반드시 정렬되어 있어야 합니다.
아래 예제를 보면서 좀더 이해해 보겠습니다.
SORT LT_EMPLOYEE BY ID.
READ TABLE LT_EMPLOYEE INTO LS_EMPLOYEE WITH KEY ID = 1001 BINARY SEARCH.
IF SY-SUBRC = 0.
ENDIF.
내부 테이블에 행이 만건이 있다고 생각해 보겠습니다. ID가 '1001'인 값을 찾기위해 READ TABLE구문을 사용했습니다.
BINARY SEARCH를 사용하지 않고 READ TABLE을 실행하면 첫행부터 순차적으로 찾기 시작합니다.
만약 찾고자 하는 값이 가장 뒷쪽에 위치해 있다면 그만큼 찾는 속도가 느리게 되겠죠.
그럼 BINARY SEARCH를 사용하게 되면 어떻게 값을 찾게되는지 보겠습니다.
BINARY SEARCH를 사용하기 위해서는 먼저 검색할 조건 기준으로 반드시 정렬을 해야합니다.
이제 ID가 1001인 값을 찾기위해 내부테이블의 중간값을 검색합니다. 중간이기 때문에 ID가 5000이 검색되었다고 했을때 1001은 5000보다 작기때문에 5000보다 뒷쪽에 있는 행들은 버리고 다시 중간값을 찾습니다.
그러면 이번엔 2500이 검색되고 1001은 2500보다 작기때문에 2500보다 뒷쪽에 있는 행들은 버리고 다시 중간값을 찾습니다. 이해 되시나요?
이런식으로 몇번 반복하게 되면 ID가 1001인 행을 찾을수 있게 됩니다.
첫행부터 순차적으로 찾는 방식보다 BINARY SEARCH방식이 속도면에서 월등하기때문에 READ TABLE구문을 사용할때는 정렬 후 BINARY SEARCH를 사용하는게 좋습니다.
예제4) TRANSPORTING NO FIELDS
READ TABLE LT_EMPLOYEE WITH KEY ID = 1001 TRANSPORTING NO FIELDS.
IF SY-SUBRC = 0.
ENDIF.
위 예제를 보면 특이하게도 INTO절이 없습니다. 그리고 뒷쪽에 TRANSPORTING NO FIELDS라는 구문이 있습니다.
TRANSPORTING NO FIELDS 구문은 내부 테이블에 조건에 맞는 값이 있는지 확인할때 사용합니다. 즉 조건에 맞는 값을 INTO절을 통해 구조체에 반영하지 않습니다. 그래서 INTO절이 없어도 됩니다.
INTO절을 써도 에러는 나지 않지만 구조체에 값이 반영되지는 않습니다.
3. LOOP AT 예제
예제1) 기본문법
TYPES: BEGIN OF TY_EMPLOYEE,
NAME TYPE STRING,
ID TYPE I,
JOINING_DATE TYPE D,
END OF TY_EMPLOYEE.
DATA : LS_EMPLOYEE TYPE TY_EMPLOYEE,
LT_EMPLOYEE TYPE TABLE OF TY_EMPLOYEE.
LS_EMPLOYEE-NAME = 'John Doe'.
LS_EMPLOYEE-ID = 1001.
LS_EMPLOYEE-JOINING_DATE = '20200301'.
APPEND LS_EMPLOYEE TO LT_EMPLOYEE.
LS_EMPLOYEE-NAME = 'Jane Doe'.
LS_EMPLOYEE-ID = 2000.
LS_EMPLOYEE-JOINING_DATE = '20200301'.
APPEND LS_EMPLOYEE TO LT_EMPLOYEE.
LOOP AT LT_EMPLOYEE INTO LS_EMPLOYEE.
ENDLOOP.
내부 테이블 LT_EMPLOYEE에는 2개의 행이 존재하기 때문에 LOOP은 순차적으로 2번 돌게 됩니다.
READ TABLE때와 마찬가지로 현재 LOOP의 대상이 되는 행을 INTO절로 구조체에 값을 전달하고 LOOP ~ ENDLOOP 사이에서 구조체의 값을 가지고 필요한 로직을 수행합니다.
예제2) WHERE
LOOP AT LT_EMPLOYEE INTO LS_EMPLOYEE WHERE ID = 1001.
ENDLOOP.
LOOP구문에 조건값을 주고 싶을땐 WHERE 구문을 사용하면 됩니다. 해당 조건에 맞는 행만 LOOP을 돌게 됩니다.
예제3) FROM [INDEX]
LOOP AT LT_EMPLOYEE INTO LS_EMPLOYEE FROM 2.
ENDLOOP.
특정 위치부터 LOOP문을 수행하고자 할때는 FROM절 다음에 위치를 지정해 주면 됩니다.