참조 : Claude Skill FILE
Oracle SQL → SAP S/4HANA Consumption Entity 전환 완전 가이드Oracle 쿼리를 AMDP로 변환하고, CDS 계층을 거쳐 OData V4 서비스로 노출하는 전체 흐름
목차
1 전체 전환 흐름
Oracle 기반 쿼리를 SAP S/4HANA에서 OData 서비스로 만들기까지 4단계를 거칩니다. 각 계층은 명확한 역할 분리를 통해 유지보수성과 재사용성을 확보합니다.
Oracle DB
기존 Oracle SQL 쿼리 — JOIN, 집계, Window 함수, DECODE/NVL 등
↓
Step 01
AMDP 변환 (SQLScript)
Oracle 문법 → HANA SQLScript · Table Function / Scalar Function / Procedure 유형 결정
Oracle 문법 → HANA SQLScript · Table Function / Scalar Function / Procedure 유형 결정
↓
Step 02
CDS Interface View (ZI_*)
AMDP Table Function을 데이터 소스로 사용 · Key / Association 선언 · UI Annotation 없음
AMDP Table Function을 데이터 소스로 사용 · Key / Association 선언 · UI Annotation 없음
↓
Step 03
CDS Consumption View (ZC_*)
@UI.lineItem · @UI.selectionField · @Consumption.filter 등 UI Annotation 집중 · Fiori Elements 연동 대상
@UI.lineItem · @UI.selectionField · @Consumption.filter 등 UI Annotation 집중 · Fiori Elements 연동 대상
↓
Step 04
OData V4 서비스 노출
Service Definition + Service Binding (OData V4 - UI) 등록
Service Definition + Service Binding (OData V4 - UI) 등록
💡 핵심 원칙: ZI_*는 데이터만 담고, UI Annotation은 ZC_*에서만 선언합니다. Association은 ZI_*에서 선언해서 ZC_*까지 전달합니다.
2 AMDP 유형 결정
Oracle 쿼리의 성격에 따라 AMDP 구현 방식을 먼저 결정합니다. 잘못된 유형 선택은 CDS View 연동 시 제약이 생기므로 이 단계가 중요합니다.
| 상황 | AMDP 유형 | 비고 |
|---|---|---|
| 복잡한 SELECT (JOIN, 집계, Window 함수) | Table Function | CDS View 데이터 소스로 직접 사용 가능 |
| 단순 계산/변환 (단일 값 반환) | Scalar Function | CDS View의 virtual element로 사용 |
| DML(UPDATE/INSERT) 또는 동적 SQL | Procedure | RAP Action/Function에서 호출 |
2-1. Table Function 기본 템플릿
CLASS zcl_amdp_##name## DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb.
CLASS-METHODS get_##entity##
IMPORTING VALUE(iv_bukrs) TYPE bukrs
VALUE(iv_date_from) TYPE erdat
VALUE(iv_date_to) TYPE erdat
RETURNING VALUE(rt_result) TYPE TABLE OF ##result_type##
RAISING cx_amdp_error.
ENDCLASS.
CLASS zcl_amdp_##name## IMPLEMENTATION.
METHOD get_##entity##
BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING ##table1## ##table2##.
RETURN
SELECT a.key_field,
a.field1,
COALESCE(b.amount, 0) AS amount -- NVL → COALESCE
FROM ##table1## AS a
LEFT OUTER JOIN ##table2## AS b
ON a.mandt = b.mandt
AND a.key_field = b.key_field
WHERE a.mandt = SESSION_CONTEXT('CLIENT')
AND a.bukrs = :iv_bukrs
AND a.erdat BETWEEN :iv_date_from AND :iv_date_to;
ENDMETHOD.
ENDCLASS.
2-2. Scalar Function 기본 템플릿
DECODE/CASE 기반 코드 변환 로직을 단일 값 반환 함수로 구현합니다.
METHOD get_##label##
BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY. " 상수 변환 시 USING 절 생략 가능
rv_text :=
CASE :iv_code
WHEN 'A' THEN '활성'
WHEN 'I' THEN '비활성'
ELSE '알 수 없음'
END;
ENDMETHOD.
3 CDS Interface View (ZI_*)
AMDP Table Function을 데이터 소스로 삼아 Interface View를 정의합니다. 이 계층은 비즈니스 로직을 담고, 재사용성을 위해 UI Annotation을 최소화합니다.
@AbapCatalog.sqlViewName: 'ZI_##NAME##' -- 고유값, 16자 이내
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: '##엔티티 설명##'
@ObjectModel.usageType: { serviceQuality: #A, sizeCategory: #M, dataClass: #TRANSACTIONAL }
define view ZI_##NAME##
as select from ZCL_AMDP_##NAME##=>GET_##ENTITY##(
iv_bukrs : ##param##,
iv_date_from : ##param##,
iv_date_to : ##param##
) as amdp_result
{
key amdp_result.key_field as KeyField,
amdp_result.amount as Amount,
-- Scalar Function 호출 (가상 필드)
ZCL_AMDP_##NAME##=>GET_##LABEL##(amdp_result.status_code) as StatusText,
_Customer -- Association 노출 -> ZC_*까지 전달
}
-- Association 선언 (UI Annotation 없음 — ZC_*에서만 선언)
association [0..1] to I_Customer as _Customer
on $projection.CustomerId = _Customer.Customer;
💡 with parameters 사용 시 파라미터 타입을 반드시 지정해야 합니다 —
with parameters p_bukrs : bukrs, p_date_from : erdat4 CDS Consumption View (ZC_*)
Interface View를 기반으로 Fiori Elements / OData V4 노출을 위한 Projection View를 정의합니다. UI Annotation과 Consumption Annotation이 이 계층에 집중됩니다.
@EndUserText.label: '##화면 레이블##'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@UI.headerInfo: {
typeName: '##단수##', typeNamePlural: '##복수##',
title: { type: #STANDARD, value: 'KeyField' }
}
define root view entity ZC_##NAME##
provider contract transactional_query
as projection on ZI_##NAME##
{
@UI.facet: [{ id: 'GeneralInfo', type: #IDENTIFICATION_REFERENCE,
label: '기본 정보', position: 10 }]
@UI.lineItem: [{ position: 10, label: '키', importance: #HIGH }]
@UI.identification: [{ position: 10 }]
key KeyField,
@UI.lineItem: [{ position: 20, label: '금액' }]
@Semantics.amount.currencyCode: 'CurrencyCode'
Amount,
@UI.hidden: true
CurrencyCode,
@Consumption.filter: { selectionType: #SINGLE, mandatory: false }
@UI.selectionField: [{ position: 10 }]
Field1,
_Customer
}
자주 쓰는 Annotation 모음
| Annotation | 용도 | 선언 위치 |
|---|---|---|
@UI.lineItem |
리스트 화면 컬럼 | Consumption |
@UI.selectionField |
검색 조건 필드 | Consumption |
@UI.identification |
오브젝트 페이지 필드 | Consumption |
@UI.facet |
오브젝트 페이지 섹션 | Consumption |
@UI.hidden |
화면 숨김 | Consumption |
@Consumption.filter |
필터 동작 제어 | Consumption |
@Semantics.amount.currencyCode |
금액 + 통화 연결 | Interface |
@Semantics.quantity.unitOfMeasure |
수량 + 단위 연결 | Interface |
@ObjectModel.text.association |
코드 → 텍스트 Association | Interface |
5 OData V4 서비스 노출
5-1. Service Definition
@EndUserText.label: '##서비스명##'
define service Z##SRV## {
expose ZC_##NAME## as ##EntitySetName##;
}
5-2. Service Binding (ADT)
| 항목 | 값 / 설명 |
|---|---|
| Binding Type | OData V4 - UI (Fiori Elements용) 또는 OData V4 - Web API |
| Service Definition | 위에서 생성한 Z##SRV## 선택 후 Activate |
| 미리보기 | Preview 버튼 → Fiori Elements List Report / Object Page 확인 |
| 권한 | Access Control(DCL) 오브젝트 별도 생성 검토 |
6 시나리오별 빠른 가이드
A 단순 Oracle SELECT → 리스트 화면
Oracle SELECT (조인 + 집계)
→ AMDP Table Function
→ ZI_* (Interface View, 파라미터 없음)
→ ZC_* (@UI.lineItem + @UI.selectionField)
→ Service Definition + Binding
→ AMDP Table Function
→ ZI_* (Interface View, 파라미터 없음)
→ ZC_* (@UI.lineItem + @UI.selectionField)
→ Service Definition + Binding
B 복잡한 Oracle 쿼리 → 파라미터 기반 조회
Oracle 쿼리 (날짜/회사코드 필터 포함)
→ AMDP Table Function (iv_bukrs, iv_date_from, iv_date_to)
→ ZI_* (with parameters)
→ ZC_* (with parameters, @Consumption.filter)
→ AMDP Table Function (iv_bukrs, iv_date_from, iv_date_to)
→ ZI_* (with parameters)
→ ZC_* (with parameters, @Consumption.filter)
C Oracle 함수/계산 로직 → Scalar Function
Oracle DECODE/CASE, 코드 변환 로직
→ AMDP Scalar Function
→ ZI_* 의 virtual element로 사용
→ ZC_* 에서 @UI.lineItem으로 노출
→ AMDP Scalar Function
→ ZI_* 의 virtual element로 사용
→ ZC_* 에서 @UI.lineItem으로 노출
7 전환 체크리스트
AMDP
Oracle 문법 변환 완료 (NVL→COALESCE, DECODE→CASE 등)
모든 테이블에
WHERE mandt = SESSION_CONTEXT('CLIENT') 추가사용 테이블 전부
USING 절에 선언Table Function:
OPTIONS READ-ONLY 선언반환 타입에 해당하는 DDIC 구조체 생성
CDS Interface View
@AbapCatalog.sqlViewName 지정 (고유값, 16자 이내)Key 필드 정의
Association 선언 (필요 시)
Scalar Function 사용 시 AMDP 클래스
USING 선언CDS Consumption View
@UI.lineItem — 리스트 컬럼 설정@UI.selectionField — 검색 조건 설정@UI.headerInfo — 오브젝트 페이지 타이틀금액 필드:
@Semantics.amount.currencyCode 연결provider contract transactional_query 선언서비스 노출
Service Definition 생성 및 활성화
Service Binding 생성 (OData V4 - UI)
Fiori Elements Preview로 화면 확인
Access Control / DCL 검토
⚠️ 주의:
provider contract transactional_query는 OData V4 서비스 노출 시 반드시 선언해야 합니다. 누락 시 Service Binding 활성화 단계에서 오류가 발생합니다.