SELECT a.FLAVOR from FIRST_HALF as a
inner join ICECREAM_INFO as b
on a.FLAVOR = b.FLAVOR
WHERE b.INGREDIENT_TYPE = 'FRUIT_BASED'
and a.TOTAL_ORDER > 3000;
2. 평균일일요금구하기
- 차량이 suv인 일평균요금 구하기
SELECT ROUND(AVG(DAILY_FEE), 0) as AVERAGE_FEE
FROM CAR_RENTAL_COMPANY_CAR
WHERE CAR_TYPE = 'SUV'
GROUP BY CAR_TYPE = 'SUV';
3. 조건에 맞는 도서 구하기
- 2021년도 인문 책의 id, 출판일 출력하기
SELECT BOOK_ID,
DATE_FORMAT(PUBLISHED_DATE, '%Y-%m-%d')
FROM BOOK
WHERE YEAR(PUBLISHED_DATE) LIKE '2021'
and CATEGORY='인문'
ORDER BY PUBLISHED_DATE;
- SUBSTRING을 사용하여, SUBSTRING(PUBLISHED_DATE, 1, 4)를 하려고 했으나, PUBLISHED_DATE가 date 형식이라서 안되었다. 조건문을 잘 확인하도록 해야겠다.
4. 파이썬 개발자 찾기
- 파이썬 skill을 할 수 있는 개발자 찾기
SELECT ID, EMAIL, FIRST_NAME, LAST_NAME
FROM DEVELOPER_INFOS
WHERE SKILL_1 = 'Python' or SKILL_2 = 'Python' or SKILL_3 = 'Python'
ORDER BY ID ASC;
5. 조건에 부합하는 중고거래 댓글 조회
- 2022-10월에 쓰인 게시판글의 글 아이디, 댓글 조회하기
SELECT a.TITLE, a.BOARD_ID, b.REPLY_ID, b.WRITER_ID, b.CONTENTS, DATE_FORMAT(b.CREATED_DATE, '%Y-%m-%d') as CREATED_DATE
FROM USED_GOODS_BOARD as a
JOIN USED_GOODS_REPLY as b
ON a.BOARD_ID = b.BOARD_ID
WHERE a.CREATED_DATE like '2022-10%'
ORDER BY b.CREATED_DATE, a.TITLE;
6. 역순정렬하기
- 젊은 동물 출력하기
SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE INTAKE_CONDITION != 'Aged'
ORDER BY ANIMAL_ID
7. 모든 레코드 조회하기
SELECT *
FROM ANIMAL_INS
ORDER BY ANIMAL_ID
8. 조건에 맞는 회원수 구하기
SELECT COUNT(*) AS USERS
FROM USER_INFOWHERE AGE >= 20 and AGE <= 29
AND YEAR(JOINED) = 2021;
9. 여러 기준으로 정렬하기
SELECT ANIMAL_ID, NAME, DATETIME
FROM ANIMAL_INS
ORDER BY NAME, DATETIME DESC
10. 가장 큰 물고기 10마리 구하기
SELECT ID, LENGTH
FROM FISH_INFO
ORDER BY LENGTH DESC, ID ASC
LIMIT 10
11. 어린 동물 찾기
SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE INTAKE_CONDITION != 'Aged'
ORDER BY ANIMAL_ID
12. 파이썬 개발자 찾기
SELECT ID, EMAIL, FIRST_NAME, LAST_NAME
FROM DEVELOPER_INFOS
WHERE SKILL_1 = 'Python' or SKILL_2 = 'Python' or SKILL_3 = 'Python'
ORDER BY ID ASC;
13. 인기 있는 아이스크림
SELECT FLAVOR
FROM FIRST_HALF
ORDER BY TOTAL_ORDER DESC, SHIPMENT_ID ASC;
14. 아픈 동물 찾기
SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE INTAKE_CONDITION = 'Sick';
15. 흉부외과 또는 일반외과 의사목록 출력
SELECT DR_NAME, DR_ID, MCDP_CD, DATE_FORMAT(HIRE_YMD, '%Y-%m-%d')
FROM DOCTOR
WHERE MCDP_CD = 'CS' OR MCDP_CD = 'GS'
ORDER BY HIRE_YMD DESC, DR_NAME ASC
16. 강원도에 위치한 생산 공장 목록 출력하기
- 공장 위치가 강원도인 공장 목록 출력하기(substring사용)
SELECT FACTORY_ID, FACTORY_NAME, ADDRESS
FROM FOOD_FACTORY
WHERE SUBSTRING(ADDRESS, 1, 3) = '강원도'
- sflight테이블에서 항공편 정보를 최대 10건까지 조회하여, 리스트 형태로 보고서를 출력하는 예제 => 고전 리스트 보고서 출력 형태
2) write option
옵션
설명
NO-GAP
출력 간 공백 없이 바로 붙여 출력
CENTERED
지정 위치에 텍스트를 가운데 정렬
LEFT-JUSTIFIED
왼쪽 정렬 (기본값)
RIGHT-JUSTIFIED
오른쪽 정렬
(len)
출력할 필드 길이 지정 (WRITE : (10) var.)
UNDER
기존에 출력된 필드 아래에 출력
AT
특정 필드 값이 바뀔 때만 출력 (AT NEW, AT END OF 이벤트와 함께 사용)
/
줄바꿈 (WRITE : / 'Hello'. → 다음 줄에 출력됨)
3) write output 포맷
4) Write as checkbox
- modify는 리스트의 line속성을 변경하는 명령어
5) WRITE AS SYMBOL
- LIST의 필드를 심볼로 보여줌
INCLUDE <SYMBOL>.
WRITE : SYM_RIGHT_HAND AS SYMBOL,
'ENJOY ABAP',
SYM_LEFT_HAND AS SYMBOL.
6) WRITE AS LINE
7) write as quickinfo
- mouse 올리면 'this is quick info'라고 뜸
- submit구문을 이용해 12-1을 호출해서 실행하면, AA 에 대한 정보가 나온다.
SUBMIT 구문이란?
다른 ABAP 리포트 프로그램을 실행시키는 명령어
마치 SE38에서 실행하듯이 실행시킴
SUBMIT zreport_name.
- 다른 리포트 프로그램 zreport_name을 실행한다.
- 실행 후 리포트가 종료되면 현재 프로그램으로는 돌아오지 않는다.
- 마치 프로그램이 넘어간 것처럼 된다
SUBMIT zreport_name AND RETURN.
- 실행 후 되돌아오게 하는 것
- 리포트가 끝나면 원래 내 프로그램으로 돌아옴
리포트에 값 넘기기
SELECT-OPTIONS: s_carr FOR sflight-carrid.
PARAMETERS: p_date TYPE sflight-fldate.
SUBMIT zreport_name
WITH s_carr IN s_carr_range
WITH p_date = '20250101'
AND RETURN.
🌠 동적으로 넘기기(중요!!)
DATA: gt_seltab TYPE TABLE OF rsparams WITH HEADER LINE.
CLEAR gt_seltab.
gt_seltab-selname = 'S_CARR'.
gt_seltab-kind = 'S'. " SELECT-OPTION
gt_seltab-sign = 'I'. " Include
gt_seltab-option = 'EQ'. " Equal
gt_seltab-low = 'AA'.
APPEND gt_seltab.
SUBMIT zreport_name
WITH SELECTION-TABLE gt_seltab
AND RETURN.
- abap 표준 구조체 RSPARAMS를 활용하면 리포트에 넘기는 값을 코드로 구성해서 넘길 수 있음
- 프로그램을 실행하면 화면에 보이는 필드들을 초기화하고, 사용자가 입력한 값에 대한 결과를 반환하는 사용자 이벤트
블록
발생
INITALIZATION
selection-screen 화면이 열리기 전 화면 필드 값을 초기화하는데 사용
AT SELECTION-SCREEN
사용자가 selection-screen에 값을 입력하기 전/후에 작동
START-OF-SELECTION
사용자가 실횅버튼을 클릭하면 LDB에서 값을 읽어옴
END-OF-SELECTION
데이터를 읽은 후의 작업을 수행하는 블록
INITALIZATION
- 이벤트 중 프로그램을 실행했을 때 가장 먼저 수행되는 것
- selection-screen이 조회되기 전에 작동하므로 변수에 초기값을 지정할 때 사용됨
- 즉, Initialization 이벤트에서 selection-screen에 사용되는 필드들의 초기값을 지정함으로써, 사용자가 자주 사용하는 값을 자동으로 입력함
위와같이 프로그래밍됨.
- select-option은 인터널 테이블 형태이기 때문에 반드시 append구문으로 데이터를 추가해야함
AT SELECTION-SCREEN
- selection-screen에서 input field의 값이 변동되었을 때 실행되는 이벤트
- initalization과 start-of-selection사이에 수행되어 사용자 액션에 대해 반응하고, 화면 필드를 조절함
1. AT SELECTION-SCREEN ON <FIELD>
- selection screen에 전달되는 특정 필드에 대해 수행
- 오류 메세지가 발생하면 해당 필드는 다시 값을 받기 위해 커서가 위치함
AT SELECTION-SCREEN ON <FIELD>.
TABLES : scarr.
SELECT-OPTIONS : s_carrid FOR scarr-carrid.
AT SELECTION-SCREEN ON s_carrid.
IF s_carrid-low <> 'AA".
Message 'It is required to input AA' TYPE 'E'.
ENDIF.
결과값!
2. AT SELECTION-SCREEN ON END OF sel
- selection screen에서 여러 건의 값을 입력할 때 전체 selection table의 입력값을 제어할 수 있음
- 하한/상한값, 미 입력 값등의 체크 시 사용 가능
AT SELECTION-SCREEN ON END OF sel.
START-OF-SELECTION & END-OF-SELECTION
- start-of-selection : 조회 화면의 필드에 대한 초기값 세팅 및 데이터 검증이 완료되면, db에서 원하는 데이터를 가져오는 작업을 수행해야함
- end-of-selection : 실행환경에서 호출되는 마지막 이벤트로서 select구문에서 모든 데이터를 읽은 후 화면에 write하기 전에 수행한다.
- 데이터베이스에서 원하는 데이터를 추출하고 해당 데이터를 정보로 활용할 수 있는 구조로 변경하여 리포트 형식으로 조회
- 자체적으로 직접 실행해서 submit을 통해 다른 프로그램에서 호출가능함
Report 프로그램은 3가지 구조로 분류됨
1. 데이터 선언부와 조회 선택화면 (Selection-Screen)
2. 실행 시점까지의 Event
3. 데이터를 뿌려주는 List Event
위 코드의 report 프로그램의 3가지 분류
1. 프로그램 및 데이터 선언
REPORT pgm_id
TABLES : sflight.
DATA : l_carrid type sflight-carrid.
SELECTION-OPTIONS: sel_carr FOR sflight-carrid.
PARAMETERS : P_carr LIKE sflight-carrid.
2. 이벤트
INITIALIZATION.
AT SELECTION-SCREEN.
START-OF-SELECTION.
...
END-OF-SELECTION.
3. List Process이벤트
TOP-OF-PAGE.
END-OF-PAGE.
AT LINE-SELECTION.
AT PF<NN>
AT USER-COMMAND.
프로그램 선언문
1) 프로그램 list heading 지정
REPORT z12_02 NO STANDARD PAGE HEADING.
이러면 heading 제목이 안나온다.
2) Line-Size
REPORT Z12_02 LINE-SIZE 30.
3) Message ID
이렇게 Message-ID를 선언하고 에러처리를 하면,
위와 같이 뜬다-!
DATA 선언
프로그램에서 사용하게 될 테이블과 데이터를 선언한다.
복잡한 프로그램에서는 INCLUDE(프로그램이름) TOP구문에 포함된다.
REPORT pgm_id
INCLUDE pgm_idTOP.
SELECTION-SCREEN
SELECT-OPTIONS: s_carrid FOR sflight-carrid.
항공사 코드 : [_____] ~ [_____] ← 여러 개 or 범위 입력 가능
- 프로그램 조회 조건을 입력하는 selection screen을 생성하는 부분
- 리포트 프로그램이 실행되면 selection-screen이 자동으로 생성됨
- selection-screen은 사용자와 상호작용하기 위한 input필드와 같이 선택 조건을 입력할 수 있는 화면을 제공
- 리포트 프로그램에서 selection screen은 'include 프로그램명sel(or TOP)에 포함하는 것이 좋음
PARAMETERS
PARAMETERS: p_carrid TYPE sflight-carrid.
항공사 코드 : [______] ← 단일 입력 가능
- parameters는 사용자가 값을 입력하도록 INPUT 필드를 정의함 <-> select-options: 여러값, 범위 선택가능
- parameters 변수와 같이 type을 지정하지 않으면 기본 char 1자리 type이 정의됨
- parameters에 입력된 값은 데이터를 조회하는 select 구문의 조건 등에 사용된다.
- 파라미터는 1개의 값만 입력받으며, 체크 박스와 같은 옵션을 추가할 수 있다.
PARAMETERS 주요 옵션 정리
옵션
설명
OBLIGATORY
필수 입력 필드로 만들어줌 (입력 안 하면 오류 발생)
DEFAULT
기본값 지정
LOWER CASE
소문자 입력 허용 (기본은 자동 대문자 변환)
AS CHECKBOX
체크박스 형태로 표시 (값은 'X' 또는 초기값)
RADIOBUTTON GROUP
라디오 버튼 그룹 지정하여 단일 선택 가능
MODIF ID
다이나믹 화면 제어 시 사용 (선택화면의 특정 항목만 ON/OFF 등)
PARAMETERS: p_name TYPE char20 OBLIGATORY,
p_age TYPE i DEFAULT 25,
p_accept AS CHECKBOX,
p_gender1 RADIOBUTTON GROUP grp1 DEFAULT 'X',
p_gender2 RADIOBUTTON GROUP grp1,
p_note TYPE char100 LOWER CASE.
p_name: 꼭 입력해야 함.
p_age: 기본값 25.
p_accept: 체크박스 (X 또는 공백).
p_gender1, p_gender2: 성별 중 택1 선택 (라디오버튼).
p_note: 소문자 허용.
Parameters와 함께 쓰이는 구문
위와 같이 결과값이 출력된다!
SELECT-OPTIONS
SELECT-OPTIONS <seltab> FOR <f>.
- 2개의 input필드를 통해 다양한 조건 값을 입력받을 수 있음
- range 변수와 같은 구조_인터널 테이블을 가지고 있다.
- select-options는 항상 for문과 같이 병핸한다.
- for문 다음으로 올 수 있는 값은 tables로 선언된 테이블 필드명이나, data로 선언된 변수이어야 한다.
옵션
설명
OBLIGATORY
필수로 입력해야 함
DEFAULT
초기값 지정
NO INTERVALS
범위 입력 안 됨 → 단일값만 입력 가능
NO-EXTENSION
여러 줄 입력 금지 → 하나의 값/조건만 입력
LOWER CASE
소문자 입력 허용
selection-screen
parameters와 selection-option을 사용하면 abap프로그램이 자동으로 필드내역과 길이를 조절하여, 화면(Selection-screen)을 생성한다.
구문
발생
selection-screen begin of line. selection-screen end of line.
- 파라미터를 여러 개 묶어서 한 라인으로 생성 - 라인에서 selection-options, selection -screen skip n구문은 사용이 안됨
selection-screen skip n.
빈 라인 n개를 삽입함
selection-screen ULINE.
Under line을 추가함 - selection-screen uline /1(10) : /는 new 라인, 위치 - selection-screen uline pos_low(10) : 파라미터 위치에서 시작 - selection-screen uline pos_high(10) : 리포트 라인 길이 끝에서 시작
selection-screen POSITION pos.
selection-screen begin of line. 블록 안에서 파라미터의 위치를 지정함
selection-screen COMMENT fmt name.
파라미터에 대한 내역을 지정 - fmt는 /pos(len) or (len)을 의미 - selection-screen comment 1(10) text-1 FOR FIELD p_1.
selection-screen PUSHBUTTON fmt name USER-COMMAND ucom.
화면 버튼을 추가하여 클릭하면 AT SELECTION-SCREEN에서 SSCRFIELDS-UCOMM에 저장됨
selection-screen BEGIN OF BLOCK block. selection-screen END OF BLOCK blcok.
- 필드 심볼을 명시하여 선언하거나 타입 없이 생성할 수 있다. 타입이 명시되지 않으면 할당되는 필드(오브젝트)의 타입을 그대로 상속받는다.
- gv_var의 변수의 값은 'A'였지만, write결과 'B'가 된것을 확인할 수 있다.
- 이는 gv_var 변수를 필드 심볼에 Assign했고, 필드 심볼의 값을 'B'로 변경했기 때문이다.
Generic TYPE Field Symbol
- 필드심볼을 선언할 때 타입을 지정하지 않고 할당되는 데이터 오브젝트 유형에 따라 기술적인 속성을 상속받게 된다.
- Field-symbols <f2> type any tablr을 사용하려면 assign 구문에서 할당할 오브젝트가 인터널 테이블 타입으로 선언되어야 한다.
- 이렇게 선언된 필드 심볼은 그 자체가 인터널 테이블이 되어 READ와 같은 구문을 사용할 수 있다.
- TABLE키워드를 삭제하고 TYPE ANY만 사용하면 LINE 타입의 구조체로 활용할 수 있다.
gv_var is B, fs is B. 이다.
- TYPE ANY는 정확한 데이터 타입을 모를 때 쓰는 가변 타입
- 필드 심볼이나, DATA ... FIELD-SYMBOLS선언 시,
- 동적으로 구조체의 필드를 참조할 때,
- Assign문과 함께 쓸 떄 사용함
- 단점으로는 정적 타입체크가 안된다는 점이 있음
Fully Type Field Symbol
- 필드 심볼을 정의할 때부터 타입이 완전히 정해진 형태로 선언
- 필드 심볼의 기술적인 속성은 할당되는 데이터 오브젝트와 같아야함
FIELD-SYMBOLS <fs3> TYPE SFLIGHT.
FIELD-SYMBOLS <fs4> LIKE LINE OF gt_tab.
- 필드심볼 <fs3>은 Sflight 테이블과 같은 구조를 가지는 구조체 타이블로 선언됨
- fs4는 인터널 테이블 Gt_tab과 같은 구조를 가지는 LINE타입의 필드심볼을 선언함
- 변수 이름은 메모리 정적인 주소를 가리키고 있다 (변수이름 = 메모리주소)
- fully type을 이용하면 명시적으로 구조체의 필드명을 호출해 사용할 수 있다
MOVE <fs3>-carrid TO <fs4>-carrid.
필드 심볼 할당
TYPES : BEGIN OF t_line,
col1 TYPE c,
col2 TYPE c,
END OF t_line.
DATA : gs_wa TYPE t_line,
gt_itab TYPE HASHED TABLE OF line WITH UNIQUE KEY col1,
key(4) TYPE c VALUE 'COL1'.
FILED-SYMBOLS <fs> TYPE ANY TABLE.
ASSIGN gt_itab TO <fs>.
- 필드 심볼에 오브젝트를 할당하려면 ASSIGN구문을 활용한다.
- ASSIGN구문 3가지 기능 분류
- assign 구문의 기본 구조
- 구조체 필드를 필드 심볼에 assign
- 필드심볼과 casting
Assign 구문의 기본구조
1. static assign
ASSIGN dobj TO <fs>.
- ASSIGN이 성공하면 시스템 변수 sy-subrc는 0, 실패하면 4를 반환함
Offset을 이용한 static assign
- 문자열의 특정위치(인덱스)부터 일부만 참조하거나 대입하는 방식 => 위치와 길이가 고정되어있기 때문에 정적 assign이라고 함
- 인덱스 기반으로 잘라서 사용하는 방법
변수+시작오프셋(길이)
1. 문자열 일부 출력
DATA lv_text TYPE string VALUE 'ABCDEFGHIJ'.
WRITE: / lv_text+0(3). " 결과: ABC
WRITE: / lv_text+3(2). " 결과: DE
WRITE: / lv_text+5(5). " 결과: FGHIJ
lv_text+3(2) -> 4번째 문자부터 2글자 출력(인덱스는 0부터 시작)
2. 일부대입(Static assign)
DATA lv_text TYPE c LENGTH 10 VALUE 'ABCDEFGHIJ'.
lv_text+2(3) = 'XYZ'.
WRITE: / lv_text. " 결과: ABXYZFGHIJ
lv_text+2(3) : 3번째 문자부터 3글자를 XYZ로 교체
3. 동적 offset
DATA lv_offset TYPE i VALUE 2.
DATA lv_len TYPE i VALUE 3.
WRITE: / lv_text+lv_offset(lv_len). " 동적으로 접근, 결과: XYZ
- runtime에 계산이 되므로 offset에 대한 동적 Offset
오프셋을 초과하면 에러가 발생하고 컴파일되지 않는다.
=> ghijkl ghijkl ghijk 가 출력
offset이 0보다 큰 값이 할당된 경우에는 애스터리스크(*)문자를 사용해야한다. => 필드 심볼이 오브젝트 길이를 넘는 것을 방지함
Assign구문의 동적인 사용
- 필드 심볼에 할당하는 필드명을 알 수 없는 경우(프포그램 내에서 동적으로 할당되는 경우) => 동적 assign구문을 이용함
ASSIGN (dobj) TO <fs>.
-> 이와 같이 답이 나온다
- assign table field to <fs>구문에서 sflight-carrid라는 필드가 존재하므로 sy-subrc = 0값을 반한함
- name1이라는 테이블 필드가 존재지 않으므로 시스템 변수 sy-subrc가 4를 반환함
구조체의 필드를 필드 심볼에 Assign
ASSIGN COMPONENT comp of STURCUTURE struc TO <fs>.
- 구조체의 개별 필드를 필드 심볼에 assign할 수 있다.
- 구조체 struc의 comp(필드)를 필드심볼 <fs>에 할당한다.
항목
첫코드
두번째 코드
접근 방법
필드의 순서(index)
필드의 이름(name)
유연성
구조체 필드명 변경돼도 잘 작동함
필드명 규칙이 바뀌면 코드도 수정 필요
용도
필드 순서 기반 처리
명명 규칙이 있는 필드에 유용
필드심볼과 casting
- 데이터 오브젝트를 필드심볼에 assign할 경우, cast를 이용해 모든 데이터 타입을 필드심볼에 Assign할 수 있다.
CAST는 암묵적 형 변환과 명시적 형 변환 2가지로 분류되어 사용됨
암묵적 형 변환(Implicit Casting)
- 필드 심볼의 data type : fully type으로 선언되어 있거나 기본 데이터 타입 -c, -n, p, x-를 사용한 경우에 암묵적 형 변환을 사용함
DATA: num TYPE i VALUE 10,
text TYPE c LENGTH 5.
text = num. " 정수 10이 문자 '10'으로 자동 변환됨
- 타입이 정해진 필드 심볼과 데이터 오브젝트 타입이 다른 경우에는 cating구문을 사용해 assign해야함
ASSIGN <var> TO <fs> CASTING.
구조체 변환
DATA: gv_addr(30) TYPE c VALUE 'Korea Seoul Twin Building'.
FIELD-SYMBOLS: <fs> TYPE t_line.
ASSIGN gv_addr TO <fs>. " ❌ 오류 발생!
gv_addr은 단순 문자형_c이고, <fs>는 구조체 t_line이기에 전혀 호환이 안된다. -> 개발자가 명확히 casting한 것으로 알려줘야함!!
명시적 형 변환(Explict Casting)
FIELD-SYMBOLS : <f1> TYPE ANY.
=>
ASSIGN ADDR TO <F1> CASTING TYPE line.
casting type구문을 이용해 정해진 타입으로 형 변환을 수행하는 것을 명시적 형 변환이라고 한다.
필드심볼과 인터널 테이블
- 변수와 같이 인터널 테이블도 같은 과정으로 필드 심볼에 할당하여 사용할 수 있다.
- 필드 심볼을 이용해 인터널 테이블을 변경하면, Work Area로 복사하는 과정이 생략되기에 성능이 향상된다
- FIELD-SYMBOLS를 쓸 때 generic하게 써야하기 때문에 type any table로 써야한다.
필드 심볼과 구조체
DATA : BEGIN OF gs_line,
col1(1) TYPE c,
col2(1) TYPE c VALUE 'X',
END OF gs_line.
FIELD-SYMBOLS <fs> LIKE gs_line.
ASSIGN gs_line TO <fs>.
MOVE <fs>-col2 TO <fs>-col1.
- 필드심볼을 구조체처럼 사용할 경우에는 필드 심볼 선언 시에 LIKE or TYPE을 선언해야함
- 필드 심볼 타입이 이미 정의되어 있다면, 필드 심볼과 기술적 속성이 같은 데이터 오브젝트만이 필드 심볼에 할당될 수 있음을 의미한다.
여기서 갑자기 드는 의문
field-symbols와 like line of등과 같은 Work area는 어떻게 다른걸까? 거의 비슷한 역할을 한다고 생각이 들었다.
구분
FIELD-SYMOLS
LIKE LINE OF로 선언한 Work Area
개념
“참조 (reference)”
“복사된 값 (copy of a row)”
메모리 방식
원본 데이터를 직접 가리킴
내부 테이블의 한 줄 값을 복사해서 저장
수정 시 영향
원본 내부 테이블이 직접 변경됨
Work area만 바뀌고 원본은 변하지 않음
성능
빠름 (복사 없음)
복사 발생 → 약간 느릴 수 있음
유연성
유연하고 동적 처리에 적합
정적이고 단순한 구조에 적합
LIKE LINE OF 예시
DATA: gt_itab TYPE STANDARD TABLE OF sflight,
gs_line LIKE LINE OF gt_itab.
LOOP AT gt_itab INTO gs_line.
gs_line-price = gs_line-price * 2. " 원본에는 영향 X
ENDLOOP.
- gs_line은 복사된 값이기 때문에, gt_itab의 실제 데이터는 수정되지 않는다.
FIELD-SYMBOLS예시
FIELD-SYMBOLS <fs> TYPE sflight.
LOOP AT gt_itab ASSIGNING <fs>.
<fs>-price = <fs>-price * 2. " 원본 데이터가 직접 바뀜
ENDLOOP.
- <fs>는 원본의 참조이므로 gt_itab의 내용이 직접 변경된다.
- 필드심볼 사용
- 참조처럼 작동해서 메모리를 직접 다룰 수 있음
- ASSIGNING을 써서 자동으로 원본 데이터를 수정할 수 있음
- 복사 없이 데이터를 바로 다를 수 있음
- 워크에어리어 사용
- 안정성이 높고, 복사한 구조체기 때문에 실수 방지에 좋음
- 코드가 명확함
- Modify, append, insert사용
- 매번 복사/복원하기에 성능이 떨어질 수도 있음
데이터 참조
PARAMETERS p_tname(30) DEFAULT 'sflight'.
- 사용자가 테이블 이름을 입력할 수 있게 함
- 기본값은 'sflight'. 아무것도 안넣으면 sflight 테이블 기준으로 실행됨
DATA: dref TYPE REF TO data.
FIELD-SYMBOLS: <fsl> TYPE any, <fs2> TYPE any.
- dref : 데이터 객체를 참조(포인터)할 수 있는 변수
- <fs1> : 테이블 구조 전체를 가르키는 필드 심볼
- <fs2> : 한 컬럼의 값을 기키는 필드 심볼
CREATE DATA dref TYPE (p_tname).
ASSIGN dref->* TO <fsl>.
- p_tname에 들어온 테이블명을 기반으로 그 테이블 구조를 동적으로 생성
- 구조를 <fs1> 필드 심볼에 연결(포인터 연결)
SELECT * FROM (p_tname) INTO <fsl> UP TO 3 ROWS.
- 사용자가 입력한 테이블에서 최대 3개의 레코드만 읽어서 <fs1>에 담는다.
- p_tname은 동적 SQL.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE <fsl> TO <fs2>.
- <fs1> 구조의 각 필드 컬럼을 순서대로 <fs2>에 할당함
- sy-index는 do루프의 반복번호다.
결과값
- 데이터 참조는 데이터 오브젝트를 가리키는 포인터, 필드 심볼을 통해 데이터 오브젝트의 값에 접근한다.
- 프로그램 실행 시점에 데이터 오브젝트는 동적으로 생성되기에 메모리 주소도 동적으로 할당됨
🔑 1. 참조 변수 (Reference Variable)
DATA dref TYPE REF TO data.
- 어떤 데이터 오브젝트(객체, 구조체, 테이블 등)의 주소를 저장하는 변수
- dref는 참조 변수
- 어떤 데이터 오브젝트의 주소를 저장하는 변수
- 자체는 데이터를 갖지 않고 있고, 어떤 오브젝트를 가르키는 역할만 함
- 아무것도 가르키지 않은 상태(dref = null 상태)
오브젝트연결
1)CREATE DATA 또는GET REFERENCE 등으로명시적 연결
CREATE DATA dref. " dref가 가리킬 메모리 공간 동적 생성
2)GET REFERENCE OF로기존 변수 연결
DATA val TYPE i VALUE 100.
GET REFERENCE OF val INTO dref.
- 기존 변수 val의 주소를 dref가 가리킴
연결 가능한 오브젝트들
타입
예시
설명
데이터 객체
DATA val TYPE i.
기본형 값, 구조, 내부 테이블 등
클래스 인스턴스
REF TO zcl_my_class
객체지향에서 클래스 인스턴스를 가리킴
동적 타입 객체
REF TO data, FIELD-SYMBOLS TYPE ANY
실제 타입은 나중에 결정됨
필드심볼
<fs>
간접접근이 가능함
참조가 연결되지 않은 상태에서 dref->* 접근 시 → Dump
반드시 IS BOUND 체크하는 습관:
IF dref IS BOUND.
ASSIGN dref->* TO <fs>.
ENDIF.
🔁 2. 역참조 (Dereferencing)
ASSIGN dref->* TO <fs>.
- 역참조는 포인터가 가르키는 주소에 저장된 데이터에 접근하는 것으로 정의됨
- 참조변수는 단지 데이터 오브젝트의 주소만 알고 있고, 실제 데이터를 사용하려면 해당 주소에 접근해야하는데 이걸 역참조라고함
- 즉, 데이터 참조가 가리키는 데이터 오브젝트의 변숫값에 접근하려면 Dereference과정을 거쳐야 한다.
- 필드 심볼에서의 casting 기능도 동일하게 사용할 수 있다.
DATA dref TYPE REF TO i. " 참조변수 선언
CREATE DATA dref. " 메모리 생성
dref->* = 100. " 역참조로 값 설정
WRITE: dref->*. " 역참조로 값 읽기
1. 구조(structure) 역참조
TYPES: BEGIN OF ty_line,
name TYPE string,
age TYPE i,
END OF ty_line.
DATA dref TYPE REF TO ty_line.
CREATE DATA dref.
dref->* = VALUE #( name = 'Wonie' age = 25 ). " 구조에 값 대입
WRITE: dref->name, dref->age. " 각 필드 직접 접근 가능
- 구조는 ->* 없이도 필드에 직접 접근이 가능함
2. 내부 테이블 참조와 역참조
TYPES: BEGIN OF ty_line,
id TYPE i,
text TYPE string,
END OF ty_line.
DATA: itab TYPE STANDARD TABLE OF ty_line,
dref TYPE REF TO data,
<itab> TYPE STANDARD TABLE.
CREATE DATA dref TYPE STANDARD TABLE OF ty_line.
ASSIGN dref->* TO <itab>.
APPEND VALUE #( id = 1 text = 'Hi' ) TO <itab>.
LOOP AT <itab> ASSIGNING FIELD-SYMBOL(<wa>).
WRITE: / <wa>-id, <wa>-text.
ENDLOOP.
- 여기서 dref->*를 통해 참조 대상 테이블 전체를 itab으로 할당
- <itab>에서 다시 한 줄씩 <wa>로 역참조하여 값 출력
->와 ->* 차이
연산자
용도
->
클래스 인스턴스의 메서드나 속성 접근 (객체지향용)
->*
데이터 오브젝트(기본형, 구조형 등) 에 대한 일반
TYPES: BEGIN OF t_struct,
col1 TYPE char15,
col2 TYPE char15,
END OF t_struct.
DATA: dref1 TYPE REF TO data,
dref2 TYPE REF TO data.
FIELD-SYMBOLS: <fs1> TYPE t_struct,
<fs2> TYPE char15.
CREATE DATA dref1 TYPE t_struct.
ASSIGN dref1->* TO <fs1>.