앞선 글에서 ABAP 실기 시험의 핵심이 CDS와 RAP이라고 했는데, 이번 글에서는 그 첫 단추인 CDS View를 실제로 만드는 방법을 처음부터 끝까지 정리합니다. BTP 트라이얼 + Eclipse(ADT) 환경 기준이며, 온프레미스 S/4HANA에서도 동일하게 적용됩니다. (환경이 아직 없다면 지난 글 “BTP 트라이얼 환경 구축”을 먼저 보고 오세요.)
1. CDS View가 뭐고, 왜 쓰는가
CDS(Core Data Services)는 데이터 모델을 데이터베이스 가까이에서 정의하는 SAP의 표준 기술입니다. 쉽게 말하면 “어노테이션(메타데이터)이 붙는 강력한 뷰” 입니다.
기존 방식과 비교하면 이해가 빠릅니다. 예전에는 ABAP 프로그램에서 SELECT + JOIN + 가공 로직을 코드로 짰다면, CDS는 그 조회 로직을 뷰로 만들어 DB 레이어에서 실행시킵니다(Code Pushdown). HANA의 성능을 제대로 쓰는 방식이고, S/4HANA의 표준 리포트(Fiori 앱)와 RAP 개발이 전부 CDS 위에서 돌아갑니다. 실기 시험에서도 CDS 작성은 사실상 필수 과제입니다.
한 가지 용어 정리: 현재 표준은 CDS View Entity(define view entity)입니다. 구형 문법(define view + @AbapCatalog.sqlViewName)은 폐기 예정이므로, 새로 배운다면 View Entity로 시작하면 됩니다. 이 글도 View Entity 기준입니다.
2. 사전 준비
- Eclipse + ADT 설치, ABAP 프로젝트 연결 (BTP 트라이얼 또는 온프레미스)
- 실습용 패키지: BTP 트라이얼이라면 본인 패키지(예: ZLOCAL 하위)에 만듭니다
- 실습 데이터: BTP 트라이얼에는 SAP가 제공하는 데모 테이블 /DMO/ 시리즈(여행 예약 시나리오)가 있어서 이걸 쓰면 됩니다. 온프레미스라면 SFLIGHT 등 데모 테이블이나 자기 Z테이블을 쓰세요.
3. CDS View 생성 실습 (기본)
3-1. 데이터 정의 생성
- Eclipse의 Project Explorer에서 패키지 우클릭 → New → Other ABAP Repository Object
- 검색창에 Data Definition 입력 → 선택 → Next
- 이름과 설명 입력. 네이밍은 관례상 다음처럼 씁니다:
- 이름:
ZI_TravelData(Z + I(Interface 뷰) + 의미) - Description:
여행 데이터 기본 뷰
- 이름:
- 트랜스포트 선택(트라이얼은 로컬) → Next
- 템플릿 선택 화면에서 Define View Entity 선택 → Finish
3-2. 기본 코드 작성
생성하면 뼈대가 나오는데, 아래처럼 완성해봅니다.
abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: '여행 데이터 기본 뷰'
define view entity ZI_TravelData
as select from /dmo/travel
{
key travel_id as TravelId,
agency_id as AgencyId,
customer_id as CustomerId,
begin_date as BeginDate,
end_date as EndDate,
@Semantics.amount.currencyCode: 'CurrencyCode'
booking_fee as BookingFee,
currency_code as CurrencyCode,
overall_status as Status
}
구조를 뜯어보면:
- @ 로 시작하는 줄이 어노테이션입니다. 뷰의 성격과 동작을 선언하는 메타데이터입니다.
@AccessControl.authorizationCheck: 권한 체크 여부. 실습에서는 #NOT_REQUIRED, 실무에서는 #CHECK + DCL(권한 정의)을 함께 만드는 것이 원칙입니다.key: 뷰의 키 필드 지정as TravelId: 필드에 별칭(CamelCase가 관례)을 부여@Semantics.amount.currencyCode: 금액 필드에 통화 필드를 연결하는 어노테이션. 금액 필드는 이걸 안 붙이면 활성화 경고가 납니다.
3-3. 활성화와 실행
- Ctrl + F3: 활성화 (문법 오류가 있으면 여기서 알려줍니다)
- F8: 데이터 미리보기 (Data Preview) — 뷰 결과가 바로 표로 조회됩니다
F8 미리보기는 CDS 개발의 가장 큰 즐거움입니다. SE38로 테스트 프로그램을 짜지 않아도 결과가 즉시 보입니다.
4. 한 단계 더: JOIN과 CASE, WHERE
실무 뷰는 대부분 여러 테이블을 엮습니다. 고객 이름을 붙여보겠습니다.
abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: '여행 데이터 + 고객 정보'
define view entity ZI_TravelWithCustomer
as select from /dmo/travel as T
inner join /dmo/customer as C
on T.customer_id = C.customer_id
{
key T.travel_id as TravelId,
T.customer_id as CustomerId,
C.last_name as CustomerName,
C.country_code as Country,
case T.overall_status
when 'O' then '진행중'
when 'A' then '승인'
when 'X' then '취소'
else '기타'
end as StatusText,
T.begin_date as BeginDate
}
where T.begin_date >= '20250101'
포인트: JOIN 문법은 SQL과 거의 같고, CASE로 코드값을 텍스트로 변환할 수 있으며, WHERE로 뷰 자체에 필터를 박을 수 있습니다. 이 밖에 산술식, 문자열 함수(concat, substring), 집계(sum, count + group by)도 지원됩니다.
5. Association — CDS의 꽃
JOIN과 비슷하지만 CDS의 진짜 무기는 Association입니다. “필요할 때만 조인되는 관계 선언”이라고 이해하면 됩니다.
abap
define view entity ZI_TravelAssoc
as select from /dmo/travel
association [0..1] to /dmo/customer as _Customer
on $projection.CustomerId = _Customer.customer_id
{
key travel_id as TravelId,
customer_id as CustomerId,
/* Association 노출 */
_Customer
}
JOIN과의 차이는 실행 시점입니다. JOIN은 뷰를 읽을 때마다 무조건 조인되지만, Association은 소비자가 _Customer.last_name처럼 경로로 접근할 때만 조인이 실행됩니다(Lazy Join). 그래서 성능에 유리하고, RAP에서 화면 간 네비게이션의 기반이 되기 때문에 실기 시험 관점에서도 Association 선언은 반드시 손에 익혀야 합니다. 관례상 Association 이름은 _(언더스코어)로 시작합니다.
6. 파라미터가 있는 뷰
조회 조건을 밖에서 받고 싶다면 파라미터를 선언합니다.
abap
define view entity ZI_TravelByAgency
with parameters
p_agency : /dmo/agency_id
as select from /dmo/travel
{
key travel_id as TravelId,
agency_id as AgencyId
}
where agency_id = $parameters.p_agency
ABAP에서 소비할 때는 SELECT * FROM ZI_TravelByAgency( p_agency = '070001' ) INTO TABLE @DATA(lt_data). 형태로 호출합니다.
7. 만든 뷰를 ABAP에서 사용하기
CDS 뷰는 ABAP SQL에서 테이블처럼 SELECT할 수 있습니다.
abap
SELECT TravelId, CustomerName, StatusText
FROM ZI_TravelWithCustomer
WHERE Country = 'DE'
INTO TABLE @DATA(lt_travel).
주의할 점: SELECT 대상은 뷰에서 정의한 별칭(CamelCase) 필드명입니다. 원본 테이블 필드명이 아닙니다.
8. 자주 만나는 오류와 팁
- 금액/수량 필드 활성화 오류: 금액에는 @Semantics.amount.currencyCode, 수량에는 @Semantics.quantity.unitOfMeasure를 붙이고 통화/단위 필드를 뷰에 포함해야 합니다.
- 네이밍 관례: 인터페이스 뷰는 ZI_, 소비(프로젝션) 뷰는 ZC_ 접두어가 표준 관례입니다. 계층을 나눠두면 RAP으로 확장할 때 그대로 이어집니다.
- 기존 define view와 혼동: 구형 문법은 SQL 뷰 이름(@AbapCatalog.sqlViewName)이 별도로 필요했지만 View Entity는 필요 없습니다. 오래된 블로그 예제를 따라 하다 이 부분에서 헤매는 경우가 많습니다.
- 성능: 뷰 위에 뷰를 계속 쌓는 것(뷰 스태킹)은 편하지만, 깊어지면 실행 계획이 복잡해집니다. 조회 화면에서 느리다면 스태킹 깊이부터 의심하세요.
- Where used: 뷰가 어디서 쓰이는지 확인은 해당 뷰에서 Ctrl+Shift+G (Where-Used List)로 봅니다. 수정 전 영향도 파악에 필수입니다.
9. 다음 단계: 여기서 RAP으로
CDS 뷰를 만들 수 있게 되면 다음 단계는 자연스럽게 이어집니다: 인터페이스 뷰(ZI_) 위에 프로젝션 뷰(ZC_)를 만들고, 메타데이터 익스텐션으로 화면 어노테이션을 붙이고, 비헤이비어를 정의하면 그게 곧 RAP 비즈니스 오브젝트입니다. 실기 시험의 핵심 과제 흐름이기도 합니다. 이 과정은 다음 글에서 RAP100 튜토리얼 기준으로 다루겠습니다.
정리하면, CDS View 생성은 “ADT에서 Data Definition 생성 → define view entity 작성 → Ctrl+F3 활성화 → F8 미리보기”의 반복입니다. 문법은 SQL과 유사해서 진입은 쉽지만, 어노테이션과 Association에서 CDS다움이 나오니 그 두 가지를 집중적으로 연습하시길 권합니다. 막히는 부분은 댓글로 남겨주세요.