본문으로 바로가기



누구나 할 수 있는 ABAP - Exercise 16: Data Retrieval Using a SELECT Loop


오늘 해볼 것은 ABAP의 시작이자 끝이라고 할 수 있는 Select로 데이터 가지고 오는 것을 해보겠다.

대부분의 비즈니스 로직이 data를 가지고 오고, 쓰고 하는것이기 때문에 그리 어려울건 없다.




목표

· 데이터베이스를 액세스 하는 루프 프로그램을 만들어라

· 입력 파라메터를 이용해 데이터를 필터링 해보자.



비즈니스 예제

사용자가 선택한 항공사의 데이터만 보여주도록 아밥 프로그램을 수정하자.



할일 1:

사용자가 입력한 조건을 읽어오자.


1.이전에 작성했던 'ZBC400_01_GS_LIST'을 복사 하던지 SAP에서 예제로 제공하는 'SAPBC400WBS_GS_LIST'를 'ZBC400_01_SELECT_SFLIGHT'로 복사하자.


2.wa_flight라고 선언되어 있는 work area를 수정하자. 해당 work area의 type은 글로벌 스트럭쳐 SBC400FOCC로 하자. 해당 스트럭처의 정보를 확인해보자.


3.항공사 코드를 입력 받는 파라메터를 선언하자.


4.SFLIGHT 데이터베이스 테이블에서 사용자가 선택한 항공사의 모든 항공 스케쥴을 가지고 오자. 그리고 앞에서 'SBC400FOCC' 타입으로 선언한 work area에 있는 필드만 가지고 오도록 하자.


5.SFLIGHT 테이블의 첫번째 key필드는 무엇인가? 위에서 작성한 SELECT 문 WHERE조건에 이 조건(mandt)이 있는가? 해당 데이터베이스 인터페이스는 primary 인덱스를 가지고 있는가?




할일 2:

예약된 항공편의 이용율을 계산하라

1.루프문을 이용해, 각 항공편의 이용율을 계산해보자. 해당 결과를 위에서 만든 work area에 있는 PERCENTAGE 필드에 넣어보자.


2.이용율을 추가하기 위해 리스트를 확장해보자.




아오... 할일1, 할일2 각 항목에 5개, 2개 총 7개의 할일이 있다.


이걸 언제 하나....?? 싶지만 하나씩 하다보면 할 수 있겠지 싶다. 고고씽.



1-1.'SAPBC400WBS_GS_LIST'를 'ZBC400_01_SELECT_SFLIGHT'로 복사하기


프로그램을 복사하기 위해 se38로 들어간다.





se38은 프로그램 조회 기능이다.

위에 문제의 요구 조건 대로 입력을 하고 상단 아이콘 중에 쓰레기통 모양 옆에 있는 '복사'버튼을 누른다.




그러면 요런 화면이 뜨는데 문제에서 정해준 이름대로 집어 넣는다.



엔터 누르면 이런 화면이 나온다. 그런데 패키지에 아무것도 없네?

있을 수도 있는데 전에 다른 작업을 해서 그런지 가끔 비어있는 일이 있다.






이전에 만들었던 패키지를 지정해 줘도 되고 본인이 임의로 만든 패키지를 지정해줘도 된다. 나는 내가 임의로 만들어 놓은 패키지에 넣기로 했다.

패키지를 생성할 때 입력했던 키워드로 검색을 한다.







그러면 해당 키워드가 포함된 패키지를 찾아준다.




나는 요놈으로 선택했다.




이건 CTS따는 화면인데 기존에 한번 했으니 패스 ok누르면 된다.




copy를 완료 했으면 한번 열어보자


그러면 아래와 같이 너무너무 간단한 소스코드가 있을 것이다.


DATA  wa_flight TYPE sflight.

SELECT * FROM sflight INTO wa_flight.

  NEW-LINE.
  WRITE:
    wa_flight-carrid,
    wa_flight-connid,
    wa_flight-fldate,
    wa_flight-seatsocc,
    wa_flight-seatsmax.

ENDSELECT.



1-1은 완료다.



다음 문제를 해결해보자.


1-2.wa_flight라고 선언되어 있는 work area를 수정하자. 해당 work area의 type은 글로벌 스트럭쳐 SBC400FOCC로 하자. 해당 스트럭처의 정보를 확인해 보자.



뭐 이런건데... 이게 뭔가 싶다 ㄹㅇ.


'일단 wa_flight라고 선언되어 있는 work area를 수정하자'라고 되어있는데 뭘 어떻게 수정하라는건지 잘 모르겠다. 그래서 다음 문장을 읽어 봤더니 type을 'SBC400FOCC'로 바꾸라는거다.



DATA  wa_flight TYPE sflight.

이 부분인데 현재 TYPE이 sflight로 되어 있다. 이 뜻이 뭐냐면 sflight라는 테이블을 참조해서 만들었다는 뜻이다.
그래서 타입을 아래와 같이 바꾸어 주라는 뜻이다.
DATA  wa_flight TYPE SBC400FOCC.

위와 같이 바꿔주라는 것.


'그리고 해당 스트럭처의 정보를 확인해보자'라고되어 있다.



ABAP EDITOR에서 저렇게 마우스로 블록잡힌 부분 'sbc400focc'를 더블클릭 해보자


그러면 이러한 화면이 나온다.


스트럭쳐 'SBC400FOCC'에 어떤 필드가 들어있는지 확인 할 수 있다.



2-2도 완료.





다음꺼 해보자.


1-3.항공사 코드를 입력 받는 파라메터를 선언하자.


'PARAMETERS'라는 명령어가 있다. 이걸 이용하면 아래 화면과 같이 무언가 입력 받을 수 있는 Text Field를 만들 수 있다.


한번 해보자. 매우 so much simple 간단 하다.





DATA  wa_flight TYPE sbc400focc.

PARAMETERS pa_car TYPE s_carr_id.

SELECT * FROM sflight INTO wa_flight.

  NEW-LINE.
  WRITE:
    wa_flight-carrid,
    wa_flight-connid,
    wa_flight-fldate,
    wa_flight-seatsocc,
    wa_flight-seatsmax.

ENDSELECT.

이 한줄만 추가 해주면 된다.
PARAMETERS pa_car TYPE s_carr_id.

그리고 Ctrl + F3을 눌러서 컴파일 하고, F8을 눌러서 실행 해볼라고 했는데 에러가 난다. ㅆ

이런 에러메세지가 나오던데... 나만 나오는건 아니지?


'"WA_FLIGHT"는 유니코드로 바꿔줄 수 없다.'라는 메세지가 나온다.


흠흠 이런.... '유니코드로 바꿔줄 수 없다'니 이게 무슨말인지 싶다. 내가 봤을 땐 유니코드 문제가 아닌 것 같은데 유니코드 에러가 나는군... 어쨋든 문제 파악을 해보자.



일단 우리가 했던 작업은 두가지다. 스트럭쳐 타입 바꾼거랑 파라메터 선언한거랑 이렇게 두가지다. 근데 파라메터 선언하는건 크게 에러날 일이 없는 것 같고 내가 봤을 땐 스트럭처 타입을 바꿔줬기 때문에 에러가 난 것이다.


기존에 스트럭처 타입은 'sflight'였는데 'sbc400focc'로 바꾸어 준 것이다.


그러면 각 타입이 어떻게 생겼는지 살펴보기로 하자.


확인 해보기 위해서 상단 t-code입력 창에 /ose11을 입력하고 엔터를 친다.



그러면 아래와 같은 화면이 나온다. 'sflight'는 database table이므로 맨 위에 'Database table'을 선택하고 sflight를 입력하고 아래 'Display'버튼을 누른다.



그러면 필드가 조회 되는데...


후루룩 보면 CARRID도 있고 CONNID도 있고.. 등등등


필드가 총 14개다.



그럼 다음 'sbc400focc'를 조회 해보자. f3을 눌러서 뒤로 간다.

'sbc400focc'는 database table이 아니고 data type이므로 'Data type'을 선택하고 아래 'Display'버튼을 누른다.



그러면...

또 휘리루리뤼루뤽 보자. CARRID도 있고 CONNID도 있는건 같은데 뭔가 허전해 보인다.


우측 상단 필드 개수를 보니 '1 / 6' 으로 되어있다. 필드가 6개밖에 없다. 그리고 뒤에 나오겠지만 'PERCENTAGE'필드는 위에 'sflight'테이블에 없는 필드이다.



sflight테이블을 조회한 결과를 'sbc400focc'라는 구조체에 집어 넣으려고 하니까 뭔가 에러사항이 발생한거다. 근데 에러메세지가 유니코드 에러라는건 좀 의외긴 하지만...


그런데 분명 문제에서는 'sbc400focc'구조체를 이용하라고 되어있다. 결론적으로 말하자면 문제가 잘못된 것은 아니다.


이러한 에러는 다음 문제 4번에서 해결해보기로 하자.



1-3번 완료. 




1-4.SFLIGHT 데이터베이스 테이블에서 사용자가 선택한 항공사의 모든 항공 스케쥴을 가지고 오자. 그리고 앞에서 'SBC400FOCC' 타입으로 선언한 work area에 있는 필드만 가지고 오도록 하자.


흠흠... 이 문제는.. 번역만 해놓으면 문제가 약간 이해가 안갈 수도 있으니 이해를 돕기 위해 어떤 싯츄에이션인지를 한번 이야기 해보겠다.


내가 여행사를 통해 비행기를 예약하려고 하는데 항공사는 꼭 '루프트한자'(LH)라는 독일 항공사를 이용하고 싶은거다. 그냥 '조회'버튼을 누르면 대한항공, 아랍애미리트항공, 케세이퍼시픽 등등 전 세계의 항공사가 다 검색이 되는데, 나는 '루프트한자' 항공사만 보고 싶은거지.


이런 경우가 이번 4번 문제 되시겠다.



4번 문제에서 요구하는건 두가지인데, 첫번째는 아까 PARAMETERS로 만들었던 Text Field로 입력받은 항공사 코드(carrid)를 select문에 where조건으로 주라는거다. 두번째는 3번에서 났던 에러를 해결하는 방법이 포함된 관련된 필드만 가지고 오라는 요구 사항이다.


하나씩 해보자.


먼저 입력 받은 항공사 코드를 select문에 where조건으로 주는 것부터 해보자.


DATA  wa_flight TYPE sbc400focc.

PARAMETERS pa_car TYPE s_carr_id.

SELECT * FROM sflight INTO wa_flight
  where carrid = pa_car.

  NEW-LINE.
  WRITE:
    wa_flight-carrid,
    wa_flight-connid,
    wa_flight-fldate,
    wa_flight-seatsocc,
    wa_flight-seatsmax.

ENDSELECT.


위와 같이 where 조건을 한줄 추가해주면 된다. 아래 한 줄이다.
SELECT * FROM sflight INTO wa_flight WHERE carrid = pa_car.


이렇게 하면 첫번째 요구조건 clear. 한번 ctrl+f3으로 컴파일 하고 실행해보고 싶지만 아직 위에 문제가 해결이 안되었기 때문에 컴파일이 안된다.



두번째 요구 조건은 테이블 sflight를 select한 것 중에서 sbc400focc 타입으로 선언한 wa_flight에 관련된 필드만 가지고 오라는 요청사항이다.


이건 'CORRESPONDING FIELDS OF'라는 명령어를 사용하면 된다.





DATA  wa_flight TYPE sbc400focc.

PARAMETERS pa_car TYPE s_carr_id.

SELECT * FROM sflight INTO CORRESPONDING FIELDS OF wa_flight
 wa_flight
  where carrid = pa_car.

  NEW-LINE.
  WRITE:
    wa_flight-carrid,
    wa_flight-connid,
    wa_flight-fldate,
    wa_flight-seatsocc,
    wa_flight-seatsmax.

ENDSELECT.

위에 select 문을 보면 뒤에 'corresponding field of'라는 구문이 추가 되었다. 이렇게 하면 됨.


그리고 Ctrl+F3을 눌러서 컴파일 후 F8을 눌러서 실행 해보자.


그러면 아래와 같은 화면이 나온다.



'루프트한자'항공을 조회하고 싶으므로 필드에 'LH'라고 입력하고 F8을 누른다.


그러면 아래와 같이 루프트한자 항공에 대한 데이터만 조회가 된다.




4번 완료.




1-5.SFLIGHT 테이블의 첫번째 key필드는 무엇인가? 위에서 작성한 SELECT 문 WHERE조건에 이 조건(mandt)이 있는가? 해당 데이터베이스 인터페이스는 primary 인덱스를 가지고 있는가?


이번 문제는 뭘 해보라는게 아니고 몇가지 질문에 대꾸만 해주면 되는 문제다.


하나씩 대꾸를 해줘보자.


'SFLIGHT 테이블의 첫번째 key필드는 무엇인가?'라는 질문.


아까 해봤던 /ose11 로 들어가서 sflight 테이블을 조회 해보자.



필드 목록이 나온다.

상단 두번째 열을 보면 'Key'라고 되어있는 열이 있다. 이게 체크표시가 되어있으면 key라는 이야기다.


고로 첫번째 key는 MANDT라는 field 되시겠다. MANDT필드는 클라이언트 번호인데 아래 그림과 같이 로그인 할 때 800번이라고 넣어준 그 필드 값을 말하는 거다.




그리고 두번째 SELECT문 WHERE조건에 이 조건(mandt)이 있는가? 인데...


fm은 where조건을 줄 때 key field를 반드시 포함시켜주어야 하는게 fm아니겠는가? 그런데 이번에 우리가 작성한 select문에는 mandt는 조건으로 주지 않았다. 그럼에도 불구하고 select문이 돌아간다. Client가 자동으로 들어간 것이다.


고로 세번째 질문인 data interface는 primary 인덱스를 가지고 있느냐에 대한 답은 이 경우는 'True'다.




5번도 완료.



이제 할일2를 해야하는데...



할일 2:

예약된 항공편의 이용율을 계산하라

1.루프문을 이용해, 각 항공편의 이용율을 계산해보자. 해당 결과를 위에서 만든 work area에 있는 PERCENTAGE 필드에 넣어보자.


2.이용율을 추가하기 위해 리스트를 확장해보자.



뭐... 이런 내용 되시겠다.



항공편의 '이용율'을 구하라고 했는데.. 이용율이 %로 나오는 값이긴 한 것 같고... 해당 항공사의 항공기의 출항 빈도를 구하면 되는건지... 아니면 해당 항공사를 이용하는 사람의 비율을 구하라는건지 문제만 봐서는 잘 모르겠다.


어찌 되었던... 우리가 할 수 있는 것은 기존에 있는 데이터를 최대한 이용하는 것이므로 먼저 데이터 베이스 테이블을 조회 해보자.



/ose11로 들어가자. 그리고 우리가 조회하는 'SFLIGHT' 테이블을 검색하자. 'SBC400FOCC'는 스트럭쳐이므로 데이터가 없다. 착오 없길. 아래 버튼 세개중에 'Display'를 누르면 된다.



조회를 누르면 관련 필드가 나온다. 단축키 Ctrl + Shift + F10 을 누르거나 그림상에 'Contents'라고 나와있는 부분에 보면 조회 하는 파란 버튼이 있다 그걸 누른다.



그러면 아래와 같이 상세 조회 화면이 나온다. 딱히 원하는 데이터가 있는게 아니고 전체적인 데이터 모양을 보고 싶은 것이므로 조건을 주지 않고 F8을 눌러서 조회 한다.



그러면 아래와 같이 테이블을 조회 한다. 필드들을 주욱 살펴보자. 맨 앞에는 Client인 MANDT필드가 있고, 그 옆에는 우리가 입력을 받는 항공사 코드인 CARRID필드가 있다. 그리고 옆에쯤 보면 SEATMAX, SEATSOCC 필드가 있다.

이걸 보면 딱 감이 오지 않는가? SEATMAX는 최대 죄석수이고 SETSOCC는 예약된 자석수 인 것 같다.


어떤 데이터를 이용할 지 감을 잡았으니 다시 문제로 돌아가보자.



2-1.루프문을 이용해, 각 항공편의 이용율을 계산해보자. 해당 결과를 위에서 만든 work area에 있는 PERCENTAGE 필드에 넣어보자.


라는 문제이다... ㅎㅎ



이용율은 SETSOCC/SEATMAX 하면 되지 싶다. 한번 소스코드에 넣어줘보자. 아래 'wa_flight-seatsmax'아래에 결과가 들어갈 변수를 선언 해주고 계산식을 넣어 주었다. 변수 선언을 하지 않고 그냥 나눈 값을 write 명령으로 출력하려고 했는데 그건 안되는 듯 하다.

DATA wa_flight TYPE sbc400focc.

PARAMETERS pa_car type s_carr_id.

data wa_flight2 type sflight.

SELECT * FROM sflight INTO CORRESPONDING FIELDS OF wa_flight
  where carrid = pa_car.

  NEW-LINE.
  WRITE:
    wa_flight-carrid,
    wa_flight-connid,
    wa_flight-fldate,
    wa_flight-seatsocc,
    wa_flight-seatsmax.

    data f_result type p LENGTH 10 DECIMALS 2.
    f_result = wa_flight-seatsocc / wa_flight-seatsmax * 100.

  write f_result.


ENDSELECT.


Ctrl+F3 컴파일 하고 F8 실행 해보자.


그리하면 오른쪽에 컬럼이 하나 추가되면서 이용율을 계산한 결과값이 화면에 나온다.



그런데 위에 소스코드에는 문제가 하나 있다. 그리고 요구조건을 모두 만족하지 않았다.


일단 문제점은 뭐냐하면 루프문 안에 변수 선언 부분을 넣어 줌으로써 소스코드가 보기 좋지 않다. 그리고 요구조건에 'sbc400focc'의 PERCENTAGE필드에 연산 수행 결과를 넣으라고 했는데 이걸 하지 않았다.


그러면 이러한 문제를 해결해보자.


PERCENTAGE 필드에 값을 넣고 해당 필드를 출력하면 될 것 같지 않은가? 한번 해보도록 하자.

DATA wa_flight TYPE sbc400focc.

PARAMETERS pa_car type s_carr_id.

data wa_flight2 type sflight.

SELECT * FROM sflight INTO CORRESPONDING FIELDS OF wa_flight
  where carrid = pa_car.

  wa_flight-percentage = wa_flight-seatsocc / wa_flight-seatsmax * 100.

  NEW-LINE.
  WRITE:
    wa_flight-carrid,
    wa_flight-connid,
    wa_flight-fldate,
    wa_flight-seatsocc,
    wa_flight-seatsmax,
    wa_flight-percentage.

ENDSELECT.
간단하다. 출력하기 전에 연산해서 percentage필드에 넣어주는 명령을 넣어주면 된다.
그리고 2번 '리스트를 확장해 보자' 라는 주문이 있는데 소스코드를 잘 보면 맨 밑에 percentage필드 출력하는 부분을 넣어줌으로써 리스트가 확장 되었다.


다 했으면 컴파일 하고 실행하자.


역시나 제대로 출력이 잘 된다.


할일2도 모두 완료.




이번 시간에는 Data Retrieving(데이터 검색하기)하는 방법을 배워 보았다. ABAP을 한다면 이러한 유형의 소스코드를 만들 일이 매우 많을 것이다. 차분히 따라해 보면서 익혀 놓으면 실전에 많은 도움이 될 것이라 본다.


그럼 이만...











댓글을 달아 주세요