본문 바로가기

SAP&ABAP

EASY ABAP - 8-2. Internal Table(2)

728x90

인터널 테이블 명령어

MOVE

TYPES : BEGIN OF T_LINE,
  COL1 TYPE I,
  COL2 TYPE I,
  END OF T_LINE.

DATA : GT_ITAB1 TYPE STANDARD TABLE OF T_LINE WITH HEADER LINE.
DATA : GT_ITAB2 TYPE STANDARD TABLE OF T_LINE.
DATA : GS_WA LIKE LINE OF GT_ITAB2.

DO 5 TIMES.
  GT_ITAB1-COL1 = SY-INDEX.
  GT_ITAB1-COL2 = SY-INDEX * 2.
  INSERT TABLE GT_ITAB1.
ENDDO.

MOVE GT_ITAB1[] TO GT_ITAB2.

LOOP AT GT_ITAB2 INTO GS_WA.
  WRITE : / GS_WA-COL1, GS_WA-COL2.
ENDLOOP.

 

CLEAR, REFRESH, FREE

- 헤더 라인이 없으면 3가지 모두 인터널 테이블의 BODY를 삭제한다.

- 헤더 라인이 있으면 CLEAR는 헤더 라인을, REFRESH와 FREE는 바디를 삭제한다.

 

- CLEAR : 데이터를 지우고 메모리 공간을 반환(RELEASSE)한다.

- REFRESH : 테이블의 내용만 삭제하고 메모리는 가지고 있는다.

- FREE : 메모리 공간을 반환한다.

- 대부분 CLEAR를 쓰고 헤더가 있는 경우 바디를 삭제할 때는 ITAB[]를 사용하여 바디를 명시하면 바디의 데이터를 삭제한다. 

 

SORT

DATA : BEGIN OF GS_LINE,
  COL1 TYPE C,
  COL2 TYPE I,
  END OF GS_LINE.


DATA : GT_ITAB LIKE STANDARD TABLE OF GS_LINE WITH NON-UNIQUE KEY COL1.

GS_LINE-COL1 = 'B'.
GS_LINE-COL2 = 3.
APPEND GS_LINE TO GT_ITAB.

GS_LINE-COL1 = 'C'.
GS_LINE-COL2 = 4.
APPEND GS_LINE TO GT_ITAB.

GS_LINE-COL1 = 'A'.
GS_LINE-COL2 = 2.
APPEND GS_LINE TO GT_ITAB.

GS_LINE-COL1 = 'A'.
GS_LINE-COL2 = 1.
APPEND GS_LINE TO GT_ITAB.

GS_LINE-COL1 = 'B'.
GS_LINE-COL2 = 1.
APPEND GS_LINE TO GT_ITAB.

SORT GT_ITAB.
PERFORM WRITE_DATA.

SORT GT_ITAB BY COL1 COL2.
PERFORM WRITE_DATA.

SORT GT_ITAB BY COL1 DESCENDING COL2 ASCENDING.
PERFORM WRITE_DATA.

SORT GT_ITAB BY COL2 COL1.
PERFORM WRITE_DATA.

FORM WRITE_DATA.
  LOOP AT GT_ITAB INTO GS_LINE.
    WRITE : / GS_LINE-COL1, GS_LINE-COL2.
  ENDLOOP.
  ULINE.
ENDFORM.

- SQL의 ORDER BY와 크게 다르지 않다.

- 그냥 SORT 명령을 실행하면 KEY 컬럼인 COL1을 기준으로 정렬을 수행한다.

 

DESCRIBE : LINES(현재 라인 수), OCCURS(초기 라인수), KIND(종류)

 

 

인터널 테이블 데이터 추가

한 라인 씩 추가, 여러 라인 추가

DATA : BEGIN OF GS_LINE,
  COL1 TYPE C,
  COL2 TYPE I,
  END OF GS_LINE.


DATA : GT_ITAB1 LIKE STANDARD TABLE OF GS_LINE WITH NON-UNIQUE KEY COL1.
DATA : GT_ITAB2 LIKE SORTED TABLE OF GS_LINE WITH NON-UNIQUE KEY COL1.

GS_LINE-COL1 = 'B'.
GS_LINE-COL2 = 1.
INSERT GS_LINE INTO TABLE GT_ITAB1.

GS_LINE-COL1 = 'A'.
GS_LINE-COL2 = 2.
INSERT GS_LINE INTO TABLE GT_ITAB1.

GS_LINE-COL1 = 'C'.
GS_LINE-COL2 = 3.
INSERT GS_LINE INTO TABLE GT_ITAB1. " 한 라인 추가

INSERT LINES OF GT_ITAB1 INTO TABLE GT_ITAB2. " 여러 라인 추가

LOOP AT GT_ITAB2 INTO GS_LINE.
  WRITE : / GS_LINE-COL1, GS_LINE-COL2.
ENDLOOP.

 

- SORTED TABLE에 INSERT하면 자동으로 정렬을 한다.

- STANDARD TABLE은 APPEND 구문과 같이 테이블 마지막에 삽입된다.

- APPEND는 STANDARD TABLE에만 쓸 수 있다. SORTED에는 순서대로 삽입해준다면 사용 가능하다.

 

*INDEX 구문을 이용하면 특정 위치에 라인을 삽입할 수도 있다. 잘 쓰이진 않을 듯 하다.

 

APPEND INITIAL LINE TO ITAB : 빈 공간 미리 생성하여 라인 추가

SORTED BY : 정렬을 수행하고 추가함. SIZE에 한계가 있어도 정렬 후 추가하기 때문에 SIZE가 꽉 찬 후 추가하더라도 순서상 앞에 와야 한다면 기존 데이터를 밀어내고 자리를 차지한다.

 

COLLECT 구문

- 인터널 테이블의 숫자 타입 칼럼을 합산하는 기능 수행

- KEY 값을 제외한 칼럼들은 Numeric Type(f, i, p)으로 선언되어야 한다. 같은 key 값이 있을 때는 숫자 타입 컬럼을 합산하고 없을 때에는 APPEND한다.

- Key 값이 없는 테이블에 COLLECT를 수행하면 CHAR 타입 컬럼들을 기준으로 같은 작업을 수행한다.

- COLLECT WA INTO ITAB.

 

DATA : BEGIN OF GS_LINE,

  COL1(3) TYPE C,
  COL2(2) TYPE N,
  COL3 TYPE I,
  END OF GS_LINE.


DATA : GT_ITAB LIKE STANDARD TABLE OF GS_LINE WITH NON-UNIQUE KEY COL1 COL2.

GS_LINE-COL1 = 'AA'.
GS_LINE-COL2 = '17'.
GS_LINE-COL3 = 660.

COLLECT GS_LINE INTO GT_ITAB.

GS_LINE-COL1 = 'AL'.
GS_LINE-COL2 = '34'.
GS_LINE-COL3 = 220.

COLLECT GS_LINE INTO GT_ITAB.

GS_LINE-COL1 = 'AA'.
GS_LINE-COL2 = '17'.
GS_LINE-COL3 = 280.

COLLECT GS_LINE INTO GT_ITAB.

LOOP AT GT_ITAB INTO GS_LINE.

  WRITE : / GS_LINE-COL1, GS_LINE-COL2, GS_LINE-COL3.

ENDLOOP.

- COL1, COL2 를 기준으로 값이 합산된 것을 확인할 수 있다.

 

 

DATA : BEGIN OF GS_LINE,
  CARRID TYPE SFLIGHT-CARRID,
  CONNID TYPE SFLIGHT-CONNID,
  PAYMENTSUM TYPE SFLIGHT-PAYMENTSUM,

  END OF GS_LINE.

DATA : GT_ITAB LIKE TABLE OF GS_LINE WITH NON-UNIQUE KEY CARRID CONNID WITH HEADER LINE.

DATA : GT_SUM LIKE TABLE OF GS_LINE WITH NON-UNIQUE KEY CARRID CONNID WITH HEADER LINE.

SELECT CARRID CONNID PAYMENTSUM
  INTO CORRESPONDING FIELDS OF TABLE GT_ITAB
  FROM SFLIGHT.


LOOP AT GT_ITAB.
  COLLECT GT_ITAB INTO GT_SUM.
ENDLOOP.

LOOP AT GT_SUM.
  WRITE : / GT_SUM-CARRID, GT_SUM-CONNID, GT_SUM-PAYMENTSUM.

ENDLOOP.

결과

인터널 테이블 데이터 변경

단건 변경

 
DATA : BEGIN OF GS_LINE,
  COL1(2) TYPE C,
  COL2 TYPE I,
  COL3 TYPE SY-DATUM,
  END OF GS_LINE.

DATA : GT_ITAB LIKE STANDARD TABLE OF GS_LINE WITH NON-UNIQUE KEY COL1 COL2.

GS_LINE-COL1 = 'AA'.
GS_LINE-COL2 = 50.
INSERT GS_LINE INTO TABLE GT_ITAB.

GS_LINE-COL1 = 'AA'.
GS_LINE-COL2 = 26.
INSERT GS_LINE INTO TABLE GT_ITAB.

GS_LINE-COL1 = 'AA'.
GS_LINE-COL2 = 50.
GS_LINE-COL3 = SY-DATUM.
MODIFY TABLE GT_ITAB FROM GS_LINE.

LOOP AT GT_ITAB INTO GS_LINE.
  WRITE : / GS_LINE-COL1, GS_LINE-COL2, GS_LINE-COL3.

ENDLOOP.

* AA         50  2020.10.29
* AA         26  0000.00.00

 

여러 건 변경

DATA : BEGIN OF GS_LINE,
  CARRID TYPE SFLIGHT-CARRID,
  CARRNAME TYPE SCARR-CARRNAME,
  FLDATA  TYPE SFLIGHT-FLDATE,

  END OF GS_LINE.

DATA : GT_ITAB LIKE TABLE OF GS_LINE.

SELECT CARRID CONNID
  INTO CORRESPONDING FIELDS OF TABLE GT_ITAB
  FROM SFLIGHT.

LOOP AT GT_ITAB INTO GS_LINE.

  AT NEW CARRID. " 새로운 GT_LINE-CARRID 일 때
    SELECT SINGLE CARRNAME INTO GS_LINE-CARRNAME
      FROM SCARR WHERE CARRID = GS_LINE-CARRID. " CARRID로 CARRNAME 가져오기

    MODIFY GT_ITAB FROM GS_LINE TRANSPORTING CARRNAME
" TRANSPORTING은 SQL의 SET과 같음 GT_ITAB-CARRNAME = GS_LINE-CARRNAME
    WHERE CARRID = GS_LINE-CARRID. " WHERE 조건으로 GT_ITAB의 여러 건 필터 후 변경

  ENDAT.

  WRITE : / GS_LINE-CARRID, GS_LINE-CARRNAME.

ENDLOOP.

 

AT 구문 정리

- AT FIRST : 인터널 테이블의 첫 번째 값이 실행될 때 수행

- AT NEW F1 : 컬럼 F1에 새로운 값이 들어올 때 수행

- AT END OF F1 : 컬럼 F1의 값이 마지막일 때 수행

- AT LAST  : 인터널 테이블의 마지막 값이 실행될 때 수행

 

 

 

INDEX를 이용해 한 라인 변경

DATA : BEGIN OF GS_LINE,
  CARRID TYPE SFLIGHT-CARRID,
  CARRNAME TYPE SCARR-CARRNAME,
  FLDATE TYPE SFLIGHT-FLDATE,
  END OF GS_LINE.

DATA : GT_ITAB LIKE TABLE OF GS_LINE.

SELECT CARRID FLDATE
  INTO CORRESPONDING FIELDS OF TABLE GT_ITAB
  FROM SFLIGHT.

LOOP AT GT_ITAB INTO GS_LINE.

  SELECT SINGLE CARRNAME
    INTO GS_LINE-CARRNAME
    FROM SCARR
   WHERE CARRID = GS_LINE-CARRID.

  MODIFY GT_ITAB FROM GS_LINE INDEX SY-TABIX.

  WRITE : / GS_LINE-CARRID, GS_LINE-CARRNAME.

ENDLOOP.

 

-  위 굵은 표시 구문에서 INDEX SY-TABIX를 지워도 결과는 같다. 즉, 해당 문구가 LOOP 안의 MODIFY에는 항상 생략되어 있다. 

 

인터널 테이블 데이터 삭제

TABLE KEY를 이용한 한 라인 삭제

- DELETE TABLE ITAB WITH TABLE KEY K1 =  F1 .... KN = FN.

 

WHERE 조건을 이용한 여러 라인 삭제

- DELETE ITAB WHERE F1 = V1.

 

INDEX를 이용한 삭제

- DELETE ITAB INDEX N.

 

 

ADJACENT DUPLICATE 구문을 이용한 중복 라인 삭제

DATA : BEGIN OF GS_LINE,
  CARRID TYPE SFLIGHT-CARRID,
  CONNID TYPE SFLIGHT-CONNID,

  END OF GS_LINE.

DATA GT_ITAB LIKE TABLE OF GS_LINE WITH HEADER LINE.

SELECT CARRID CONNID INTO CORRESPONDING FIELDS OF TABLE GT_ITAB
  FROM SFLIGHT.

DELETE ADJACENT DUPLICATES FROM GT_ITAB.

LOOP AT GT_ITAB.

  WRITE : / GT_ITAB-CARRID, GT_ITAB-CONNID.

ENDLOOP.

중복 제거(왼쪽), 중복 제거 x(오른쪽)

 

 

인터널 테이블 읽기

- 인터널 테이블을 읽을 때는 READ 구문을 사용한다

 

KEY 값을 이용한 READ

DATA : BEGIN OF GS_LINE,
  CARRID TYPE SCARR-CARRID,
  CARRNAME TYPE SCARR-CARRNAME,
  END OF GS_LINE.

DATA : GT_ITAB LIKE TABLE OF GS_LINE WITH NON-UNIQUE KEY CARRID.

SELECT CARRID CARRNAME
  INTO CORRESPONDING FIELDS OF TABLE GT_ITAB
  FROM SCARR.

GS_LINE-CARRID = 'AA'.
READ TABLE GT_ITAB FROM GS_LINE INTO GS_LINE.

WRITE : / GS_LINE-CARRID, GS_LINE-CARRNAME.

CLEAR : GS_LINE.

READ TABLE GT_ITAB WITH TABLE KEY CARRID = 'AB' INTO GS_LINE.

WRITE : / GS_LINE-CARRID, GS_LINE-CARRNAME.

 

WORK AREA 할당

1. READ 구문의 COMPARING 옵션

DATA : BEGIN OF GS_LINE,
  COL1 TYPE C,
  COL2 TYPE I,

  END OF GS_LINE.

DATA : GT_ITAB LIKE SORTED TABLE OF GS_LINE WITH UNIQUE KEY COL1.

GS_LINE-COL1 = 'A'.
GS_LINE-COL2 = 1.
INSERT GS_LINE INTO TABLE GT_ITAB.

CLEAR GS_LINE.

GS_LINE-COL1 = 'B'.
GS_LINE-COL2 = 2.
INSERT GS_LINE INTO TABLE GT_ITAB.

CLEAR GS_LINE.

GS_LINE-COL1 = 'A'.

WRITE : / 'BEFORE READ : ', GS_LINE-COL1, GS_LINE-COL2.

READ TABLE GT_ITAB FROM GS_LINE INTO GS_LINE COMPARING COL2.

WRITE : / 'SY-SUBRC : ', SY-SUBRC. " 값이 달라서 2 반환

WRITE : / 'RESULT : ', GS_LINE-COL1, GS_LINE-COL2.

 

 

2. READ 구문의 TRASNPORTING 옵션

- TRANSPORTING은 READ한 결과를 해당 컬럼만 TARGET에 저장하는 기능을 수행한다.

DATA : BEGIN OF GS_LINE,
  COL1 TYPE C,
  COL2(7) TYPE C,

  END OF GS_LINE.

DATA : GT_ITAB LIKE SORTED TABLE OF GS_LINE WITH UNIQUE KEY COL1.
DATA : GS_WA LIKE LINE OF GT_ITAB.

GS_LINE-COL1 = 'A'.
GS_LINE-COL2 = 'FIRST'.ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
INSERT GS_LINE INTO TABLE GT_ITAB.
CLEAR GS_LINE.

GS_LINE-COL1 = 'B'.
GS_LINE-COL2 = 'SECOND'.
INSERT GS_LINE INTO TABLE GT_ITAB.
CLEAR GS_LINE.

GS_LINE-COL1 = 'A'.

READ TABLE GT_ITAB WITH TABLE KEY COL1 = 'A' INTO GS_WA TRANSPORTING COL2.

WRITE : / 'COL1 : ', GS_WA-COL1, ' COL2 : ', GS_WA-COL2.

 

- COL2에만 값이 삽입된다. GS_LINE을 CLEAR하고 COL2만 TRANSPORTING하는 듯

 

인덱스 활용 READ구문

READ TABLE GT_ITAB INDEX 1.

 

READ BINARY SEARCH

- STANDARD TYPE의 인터널 테이블을 READ할 때 이용 가능. 대상 컬럼을 기준으로 SORT한 후 사용하며 READ 속도가 일반 READ 속도보다 따르다.

DATA : BEGIN OF GS_LINE,
  CARRID TYPE SFLIGHT-CARRID,
  CARRNAME TYPE SCARR-CARRNAME,

  END OF GS_LINE.

DATA : GT_ITAB LIKE TABLE OF GS_LINE.
DATA : GT_SCARR LIKE TABLE OF SCARR WITH HEADER LINE.

SELECT CARRID CONNID
  INTO CORRESPONDING FIELDS OF TABLE GT_ITAB
  FROM SFLIGHT.

SELECT CARRID CARRNAME
  INTO CORRESPONDING FIELDS OF TABLE GT_SCARR
  FROM SCARR.

LOOP AT GT_ITAB INTO GS_LINE.
  READ TABLE GT_SCARR WITH KEY CARRID = GS_LINE-CARRID BINARY SEARCH.

  GS_LINE-CARRNAME = GT_SCARR-CARRNAME.
  MODIFY GT_ITAB FROM GS_LINE.

  WRITE : / GS_LINE-CARRID, GS_LINE-CARRNAME.
ENDLOOP.

- 매번 테이블에 접근하지 않고 테이블의 모든 데이터를 인터널 테이블에 저장한 후에 BINARY SEARCH를 이용해 항공사 이름을 할당하여 속도가 더 빠르다. 그 이유는 데이터베이스에 여러번 다녀오지 않고 APPLICATION SERVER에서 인터널 테이블을 활용하기 때문이다.

728x90