본문 바로가기

어쩌다 SAP/어쩌다 ABAP

9일차) 인터널 테이블 데이터 추가, 변경, 삭제, 읽기

6. 인터널 테이블 데이터 추가

1. INSERT 구문

1) Table Key를 이용해 한 라인 추가

- INSERT구문이 성공하면 SY-SUBRC에 0이 저장.

INSERT line INTO TABLE itab.

2) Table Key를 이용해 여러 라인 추가

- itab1과 itab2가 같은 line type이라면 INSERT구문으로 여러 라인을 삽입할 수 있다.

<예제 5-19>

*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.
* (*INSERT LINES OF gt_itab1 FROM 1 TO 2 INTO TABLE gt_itab2.)
*
*LOOP AT gt_itab2 INTO gs_line..
*  WRITE: / gs_line-col1, gs_line-col2.
*ENDLOOP.

- gt_itab2가 Sorted Table이라 INSERT LINES OF 구문에서 정렬된 col1값을 기준으로 정렬되어 출력

 

3) Index를 이용해 한 라인 추가

- INDEX 구문을 이용하면 Index값 위치에 라인 삽입.

-Hashed Type의 인터널 테이블에는 INDEX 구문 사용할 수 없다.

<INDEX구문으로 한 라인 추가>

INSERT line INTO itab [Index idx].
<INDEX구문으로 여러 라인 추가>

INSERT lines of itab1 INTO itab2 [Index idx].

 

4) 인터널 테이블 타입에 따른 INSERT 효과

(1)Standard Table

- 데이터가 인터널 테이블 마지막 위치에 추가

- APPEND 구문과 같은 효과

(2)Sorted Table

- 데이터가 인터널 테이블의 순서에 따라 추가

- Non-UNIQUE KEY 타입이면, Duplicate Line은 같은 Key 위에 추가.

(3)Hashed Table

- 데이터가 Table Key의 Hash Index 순서에 따라 추가.

<예제 5-20>

*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.
(**DATA gt_itab LIKE SORTED TABLE OF gs_line WITH UNIQUE KEY col1.) 
(**DATA gt_itab LIKE HASHED TABLE OF gs_line WITH UNIQUE KEY col1.)
*
*gs_line-col1 = 'B'.
*gs_line-col2 = 1.
*INSERT gs_line INTO TABLE gt_itab.
*
*gs_line-col1 = 'A'.
*gs_line-col2 = 2.
*INSERT gs_line INTO TABLE gt_itab.
*
*gs_line-col1 = 'A'.
*gs_line-col2 = 3.
*INSERT gs_line INTO TABLE gt_itab.
*
*gs_line-col1 = 'C'.
*gs_line-col2 = 4.
*INSERT gs_line INTO TABLE gt_itab.
*BREAK-POINT.

 

2. APPEND 구문을 이용한 Table Line 추가

- INSERT 구문은 Key와 Index를 이용해 인터널 테이블에 데이터를 추가한다.

- APPEND 구문은 Index만 이용할 수 있기 때문에 Hashed Type의 인터널 테이블에는 사용할 수 없다.

 

1) 한 라인 추가

- APPEND 후에는 SY-TABIX에 Index번호를 저장

APPEND Line TO itab.

2) 여러 라인 추가

APPEND Lines OF itab1 [FROM n1] [TO n2] TO itab2.
<예제 5-21>

*DATA: BEGIN OF gs_line,
*        col1 TYPE c,
*        col2 TYPE n,
*      END OF gs_line.
*
*DATA gt_itab LIKE STANDARD TABLE OF gs_line WITH NON-UNIQUE KEY col1.
* (*DATA gt_itab LIKE SORTED TABLE OF gs_line WITH UNIQUE KEY col1.)
* (*DATA gt_itab LIKE HASHED TABLE OF gs_line WITH UNIQUE KEY col1.) 
*
*gs_line-col1 = 'B'.
*gs_line-col2 = 1.
*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 = 3.
*APPEND gs_line TO gt_itab.
*
*gs_line-col1 = 'C'.
*gs_line-col2 = 4.
*APPEND gs_line TO gt_itab.
*
*BREAK-POINT.

3) 인터널 테이블 타입에 따른 APPEND 효과

(1) Standard table

- 인터널 테이블 제일 마지막 위치에 추가

- SORTED BY 옵션을 이용해 Key 값 기준 DESCENDING 정렬하면서 추가됨

(2) Sorted table

- 데이터가 정렬된 상태로 인터널 테이블에 추가되도록 로직 구성하지 않으면 덤프 뜬다.

(3) Hashed table

- APPEND 구문 사용 불가

 

4) APPEND INITIAL LINE

- 인터널 테이블을 빈 공간에서 미리 생성한 후, 라인을 추가할 수 있다.

- SORTED BY 구문을 사용하면 DESCENDING 정렬을 수행한다. Standard type 인터널 테이블만 효과있고 INITIAL SIZE로 크기를 지정해야한다.

<예제 5-22> - SORTED BY 구문의 효력

*DATA: BEGIN OF gs_line,
*        col1 TYPE c,
*        col2 TYPE i,
*      END OF gs_line.
*
*DATA gt_itab LIKE TABLE OF gs_line INITIAL SIZE 2.
*
*gs_line-col1 = 'C'.
*gs_line-col2 = 1.
*APPEND gs_line TO gt_itab SORTED BY col1.
*
*gs_line-col1 = 'A'.
*gs_line-col2 = 2.
*APPEND gs_line TO gt_itab SORTED BY col1.
*
*gs_line-col1 = 'B'.
*gs_line-col2 = 3.
*APPEND gs_line TO gt_itab SORTED BY col1.
*
*LOOP AT gt_itab INTO gs_line.
*  WRITE: / gs_line-col1, gs_line-col2.
*ENDLOOP.
---------------------------------------------------------------------------------------
1 - INITIAL SIZE 2
2 - DESCENDING SORT APPEND          "COL1 = A"인 라인 제거

 

3. COLLECT 구문

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

COLLECT wa INTO itab.
<예제 5-23>

*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.
<예제 5-24> - 항공기 ID별 예약 총 비용 추출(sflight 테이블 이용)

*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.

7. 인터널 테이블 데이터 변경

- MODIFY 구문을 사용하면 인터널 테이블의 한 라인을 변경할 수 있다.

 

1. Table Key를 이용해 한 라인 변경
MODIFY TABLE itab FROM wa [TRANSPORTING f1 f2 ...].

- TRANSPORTING 구문을 이용해 해당 칼럼만 변경할 수 있다.

<예제 5-25>

*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 = '20201029'.
*
*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.

 

2. WHERE 조건을 이용해 여러 라인 변경

- 하나 이상의 라인을 변경하는 경우 WHERE 구문을 사용한다.

<예제 5-26>

*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 connid INTO CORRESPONDING FIELDS OF TABLE gt_itab FROM sflight.
*
*LOOP AT gt_itab INTO gs_line.
*
*  AT NEW carrid.
*
*    SELECT SINGLE carrname INTO gs_line-carrname
*    FROM scarr WHERE carrid = gs_line-carrid.
*
*    MODIFY gt_itab FROM gs_line TRANSPORTING carrname
*    WHERE carrid = gs_line-carrid.
*  ENDAT.
*
*  WRITE : / gs_line-carrid, gs_line-carrname.
*
*ENDLOOP.

- AT NEW 구문은 인터널 테이블을 LOOP 처리하면서 해당 칼럼에 새로운 값이 들어온 경우 실행.

- AA AZ DL처럼 새로운 ID로 변경될 때마다 실행되고, MODIFY 구문에서 WHERE조건을 이용해 항공사 이름 변경.

 

3. INDEX를 이용해 한 라인 변경

- INDEX를 이용해 갑을 변경하기 때문에 Standard, Sorted 타입 인터널 테이블에서만 사용 가능.

- LOOP 구문 내에서는 INDEX 옵션 생략 가능하며, 이 때 Line index 값을 변경함.

<예제 5-27>

*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.
* ( MODIFY gt_itab FROM gs_line INDEX sy-tabix.)
* ( MODIFY gt_itab (헤더라인 있으면 생략가능) )
*
*  WRITE : / gs_line-carrid, gs_line-carrname.
*
*ENDLOOP.

 

8. 인터널 테이블 데이터 삭제

1. Table Key를 이용해 한 라인 삭제

- DELETE 구문으로 인터널 테이블의 라인을 삭제한다.

- Non-Unique Key로 설정된 Standard Type의 경우 WITH TABLE KEY 구문은 중복된 Key 데이터 중 한 건만 삭제.

DELETE TABLE itab [FROM wa].

DELETE TABLE itab WITH TABLE KEY k1 = f1 ... kn = fn.

 

2. WHERE 조건을 이용해 여러 라인 삭제
DELETE itab WHERE cond.
<예제 5-28>

*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 NON-UNIQUE KEY carrid.
*
*SELECT carrid connid fldate
*  INTO CORRESPONDING FIELDS OF TABLE gt_itab FROM sflight.
*
*  DELETE gt_itab WHERE carrid = 'AA' AND connid = '0017'.
*
*  LOOP AT gt_itab INTO gs_line.
*
*    WRITE : / gs_line-carrid, gs_line-connid.
*
*  ENDLOOP.

 

3. INDEX를 이용해 삭제
DELETE itab [INDEX idx].

-INDEX 이용해 여러라인 삭제 (Hashed type 인터널 테이블에서 사용 불가)

<Index n1~n2 사이의 Line을 삭제>

DELETE itab FROM n1 TO n2.
DELETE itab FROM n1.
DELETE itab TO n2.
<예제 5-29>

*DATA: BEGIN OF gs_line,
*        col1 TYPE i,
*        col2 TYPE i,
*      END OF gs_line.
*
*DATA gt_itab LIKE TABLE OF gs_line.
*
*DO 3 TIMES. *  gs_line-col1 = sy-index.
*  gs_line-col2 = sy-index * 2.
*  APPEND gs_line TO gt_itab.
*ENDDO.
*
*DELETE gt_itab INDEX 2.
*
*LOOP AT gt_itab INTO gs_line.
*  WRITE : / gs_line-col1, gs_line-col2.
*ENDLOOP.
---------------------------------------------------
2번째 index를 삭제했기에 col1 = 2, col2 = 4 line이 결과에 나타나지 않음.

 

4. ADJACENT DUPLICATE 구문을 이용해 중복 라인 삭제

- ADJACENT DUPLICATE 구문을 이용하면 중복된 라인을 삭제할 수 있다.

- ADJACENT DUPLICATE 구문 수행 전 SORT 구문으로 인터널 테이블을 정렬해야 한다.

 

DELETE ADJACENT DUPLICATE ENTRIES FROM itab
                      [COMPARING f1 f2 ... | ALL FIELDS] .

- COMPARING 구문 사용 안하면 Table Key 값이 중복된 데이터를 삭제

<예제 5-30>

*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.

 

9. 인터널 테이블 읽기

- READ 구문을 사용해서 인터널 테이블에서 원하는 데이터를 읽는다.

- READ 구문을 사용하면 헤더라인이 있는 경우 헤더라인으로 해당 데이터가 복사되고, 그렇지 않으면 Work Area에 복사해야한다.

 

1. Table Key 이용
READ TABLE itab FROM wa INTO result.
READ TABLE itab WITH TABLE KEY k1 = f1 . kn = fn INTO result
<예제 5-31> - 인터널 테이블의 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.

 

2. Work Area 할당

- READ 구문 수행 결과를 Work Area로 할당하는 구문이다.

 

1) READ 구문의 COMPARING 옵션

- COMPARING 구문은 READ 구문의 결괏값에 비교 조건을 추가한다.

- WA의 값과 itab에 존재하는 값이 같으면 SY-SUBRC = 0를 반환하고, 같지 않으면 SY-SUBRC = 2를 반환한다.

<예제 5-32>

*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-col1 = 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'.
*
*READ TABLE gt_itab FROM gs_line INTO gs_line COMPARING col2.
*
*WRITE : / 'SY-SUBRC is : ', sy-subrc.
*WRITE : / 'Result is : ', gs_line-col1, gs_line-col2.

Q) 설명좀 COMPARING이 여기서 왜 필요함?

 

2) READ 구문의 TRANSPORTING 옵션

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

<예제 5-33>

*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 is :', gs_wa-col1, 'col2 is :', gs_wa-col2.
-------------------------------------------------------------------
Col1 is :  Col2 is : First

 

3. INDEX를 이용해 READ 구문 수행

- Hashed Type 인터널 테이블에서 사용 불가

READ TABLE itab INDEX idx INTO result.
<예제 5-34>

*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.
*
*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.
*
*READ TABLE gt_itab INTO gs_line INDEX 1.
*WRITE : / 'Col1 is :', gs_line-col1, 'Col2 is :', gs_line-col2.

 

4. READ BINARY SEARCH
<예제 5-35>

*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.

C.F) DUMP ERROR  - 291p

 

 

출처: https://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788965400288

 

Easy ABAP 2.0 - 교보문고

기본 이론과 실무 예제로 새롭게 꾸민『Easy ABAP 2.0』. 기본 이론과 예제 프로그램의 실습으로 단계적으로 ABAP 프로그램을 완성해갈 수 있도록 구성된 교재이다. 이론 부분은 1장 ~ 11장으로 구성��

www.kyobobook.co.kr