ABAP CDS Views: Core Data Services verstehen und nutzen

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

CDS Views (Core Data Services) sind die moderne Art, Datenmodelle in SAP zu definieren. Sie ermöglichen semantisch reiche, wiederverwendbare Datendefinitionen direkt auf Datenbankebene mit Push-Down-Optimierung für HANA.

Was sind CDS Views?

CDS Views sind:

  • Deklarative SQL-Erweiterungen für semantische Datenmodellierung
  • Datenbankviews mit erweiterten Funktionen (Annotationen, Assoziationen)
  • Grundlage für SAP Fiori, RAP und moderne SAP-Entwicklung
  • Performant durch Push-Down auf die Datenbank (HANA)

Grundlegende Syntax

@AbapCatalog.sqlViewName: 'ZSQL_VIEW_NAME'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Beschreibung der View'
define view Z_CDS_VIEW_NAME
as select from <datenquelle>
{
<feldliste>
}

Beispiele

1. Einfache CDS View

@AbapCatalog.sqlViewName: 'ZSQLCUSTOMERS'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Kundenstammdaten'
define view Z_I_Customers
as select from kna1
{
key kunnr as CustomerId,
name1 as CustomerName,
ort01 as City,
land1 as Country,
erdat as CreatedDate
}

2. CDS View in ABAP verwenden

" CDS View wie eine Tabelle verwenden
SELECT * FROM z_i_customers
INTO TABLE @DATA(lt_customers)
WHERE country = 'DE'.
LOOP AT lt_customers INTO DATA(ls_customer).
WRITE: / ls_customer-customerid, ls_customer-customername.
ENDLOOP.
" Mit Inline-Deklaration
SELECT customerid, customername, city
FROM z_i_customers
WHERE country = 'DE'
INTO TABLE @DATA(lt_german_customers).

3. CDS View mit JOIN

@AbapCatalog.sqlViewName: 'ZSQLORDERCUST'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Bestellungen mit Kundendaten'
define view Z_I_OrdersWithCustomer
as select from vbak as order
inner join kna1 as customer
on order.kunnr = customer.kunnr
{
key order.vbeln as OrderNumber,
order.erdat as OrderDate,
order.netwr as NetValue,
order.waerk as Currency,
customer.kunnr as CustomerId,
customer.name1 as CustomerName,
customer.ort01 as CustomerCity
}

4. LEFT OUTER JOIN

define view Z_I_CustomersWithOrders
as select from kna1 as customer
left outer join vbak as order
on customer.kunnr = order.kunnr
{
key customer.kunnr as CustomerId,
customer.name1 as CustomerName,
order.vbeln as OrderNumber,
order.netwr as OrderValue
}

5. Berechnete Felder (Calculated Fields)

@AbapCatalog.sqlViewName: 'ZSQLORDERCALC'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Bestellungen mit Berechnungen'
define view Z_I_OrderCalculations
as select from vbak
{
key vbeln as OrderNumber,
netwr as NetValue,
waerk as Currency,
// Berechnungen
netwr * 1.19 as GrossValue,
// Bedingungen mit CASE
case
when netwr >= 10000 then 'HIGH'
when netwr >= 1000 then 'MEDIUM'
else 'LOW'
end as ValueCategory,
// Datumsfunktionen
dats_days_between( erdat, $session.system_date ) as DaysSinceOrder
}

6. Aggregationen

@AbapCatalog.sqlViewName: 'ZSQLCUSTTOTAL'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Kundenumsätze aggregiert'
define view Z_I_CustomerTotals
as select from vbak
{
key kunnr as CustomerId,
// Aggregatfunktionen
sum( netwr ) as TotalOrderValue,
count(*) as OrderCount,
avg( netwr ) as AverageOrderValue,
min( erdat ) as FirstOrderDate,
max( erdat ) as LastOrderDate
}
group by kunnr

7. Assoziationen (Associations)

@AbapCatalog.sqlViewName: 'ZSQLORDERASSOC'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Bestellungen mit Assoziationen'
define view Z_I_Orders
as select from vbak as Order
association [1..1] to kna1 as _Customer
on $projection.CustomerId = _Customer.kunnr
association [0..*] to vbap as _Items
on $projection.OrderNumber = _Items.vbeln
{
key vbeln as OrderNumber,
kunnr as CustomerId,
erdat as OrderDate,
netwr as NetValue,
// Assoziationen exponieren
_Customer,
_Items
}

8. Assoziationen in ABAP nutzen

" Path Expression nutzen
SELECT OrderNumber,
OrderDate,
NetValue,
\_Customer-name1 as CustomerName,
\_Customer-ort01 as CustomerCity
FROM z_i_orders
INTO TABLE @DATA(lt_orders_with_customer).
" Mit WHERE auf Assoziation
SELECT *
FROM z_i_orders
WHERE \_Customer-land1 = 'DE'
INTO TABLE @DATA(lt_german_orders).

9. Parameter in CDS Views

@AbapCatalog.sqlViewName: 'ZSQLORDERPARAM'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Bestellungen mit Parameter'
define view Z_I_OrdersByDate
with parameters
p_from_date : abap.dats,
p_to_date : abap.dats
as select from vbak
{
key vbeln as OrderNumber,
erdat as OrderDate,
netwr as NetValue,
kunnr as CustomerId
}
where erdat >= $parameters.p_from_date
and erdat <= $parameters.p_to_date

10. Parametrisierte View in ABAP

" Parameter übergeben
SELECT *
FROM z_i_ordersbydate( p_from_date = '20240101',
p_to_date = '20241231' )
INTO TABLE @DATA(lt_orders_2024).
" Mit Variablen
DATA: lv_from TYPE d VALUE '20240101',
lv_to TYPE d VALUE '20241231'.
SELECT *
FROM z_i_ordersbydate( p_from_date = @lv_from,
p_to_date = @lv_to )
INTO TABLE @DATA(lt_orders).

11. Annotationen für UI (Fiori)

@AbapCatalog.sqlViewName: 'ZSQLCUSTUI'
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Kunden für UI'
@UI.headerInfo: {
typeName: 'Kunde',
typeNamePlural: 'Kunden',
title: { value: 'CustomerName' }
}
define view Z_C_Customers
as select from z_i_customers
{
@UI.facet: [{ position: 10, type: #IDENTIFICATION_REFERENCE }]
key @UI.lineItem: [{ position: 10 }]
@UI.identification: [{ position: 10 }]
CustomerId,
@UI.lineItem: [{ position: 20 }]
@UI.identification: [{ position: 20 }]
@UI.selectionField: [{ position: 10 }]
CustomerName,
@UI.lineItem: [{ position: 30 }]
@UI.selectionField: [{ position: 20 }]
City,
@UI.lineItem: [{ position: 40 }]
Country
}

12. Access Control (DCL)

@EndUserText.label: 'Zugriffskontrolle für Kunden'
@MappingRole: true
define role Z_I_Customers_Role {
grant select on Z_I_Customers
where Country = aspect pfcg_auth( ZAUTH_OBJ, ZLAND, ACTVT = '03' );
}

13. UNION und UNION ALL

define view Z_I_AllPartners
as select from kna1
{
key kunnr as PartnerId,
name1 as PartnerName,
'CUSTOMER' as PartnerType
}
union all
select from lfa1
{
key lifnr as PartnerId,
name1 as PartnerName,
'SUPPLIER' as PartnerType
}

14. CDS Table Functions (AMDP)

@EndUserText.label: 'CDS Table Function'
define table function Z_TF_ComplexLogic
with parameters
p_date : abap.dats
returns {
key OrderId : abap.char(10);
Amount : abap.curr(15,2);
Status : abap.char(1);
}
implemented by method
zcl_complex_logic=>get_orders;
CLASS zcl_complex_logic DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb.
CLASS-METHODS get_orders
FOR TABLE FUNCTION z_tf_complexlogic.
ENDCLASS.
CLASS zcl_complex_logic IMPLEMENTATION.
METHOD get_orders BY DATABASE FUNCTION FOR HDB
LANGUAGE SQLSCRIPT OPTIONS READ-ONLY
USING vbak.
RETURN SELECT vbeln as orderid,
netwr as amount,
'A' as status
FROM vbak
WHERE erdat = :p_date;
ENDMETHOD.
ENDCLASS.

15. Extend Views

@AbapCatalog.sqlViewAppendName: 'ZSQLCUSTEXT'
@EndUserText.label: 'Erweiterung für Kunden'
extend view Z_I_Customers with Z_E_Customers_Extension
{
// Zusätzliche Felder aus anderen Tabellen
kna1.brsch as Industry,
kna1.kukla as CustomerClass
}

CDS View Typen

TypPräfixZweck
Interface ViewI_ oder Z_I_Basis-Datenmodell, wiederverwendbar
Consumption ViewC_ oder Z_C_UI-spezifisch, mit UI-Annotationen
Basic ViewR_ oder Z_R_Restricted, für interne Nutzung
Extension ViewE_ oder Z_E_Erweiterungen bestehender Views

Wichtige Annotationen

// Katalog-Annotationen
@AbapCatalog.sqlViewName: 'SQL_NAME' // SQL View Name (max 16 Zeichen)
@AbapCatalog.compiler.compareFilter: true // Filteroptimierung
@AbapCatalog.preserveKey: true // Schlüssel erhalten
@AbapCatalog.buffering.status: #ACTIVE // Pufferung aktivieren
// Zugriffskontrolle
@AccessControl.authorizationCheck: #CHECK // Berechtigungsprüfung
@AccessControl.authorizationCheck: #NOT_REQUIRED
// Metadaten
@EndUserText.label: 'Beschreibung'
@ObjectModel.representativeKey: 'FieldName'
@ObjectModel.semanticKey: ['Field1', 'Field2']
// Analytics
@Analytics.dataCategory: #CUBE
@Analytics.dataCategory: #DIMENSION
// OData/Fiori
@OData.publish: true
@UI.headerInfo.typeName: 'Entity'

CDS Funktionen

// String-Funktionen
concat( field1, field2 )
substring( field, position, length )
length( field )
upper( field )
lower( field )
ltrim( field, char )
rtrim( field, char )
// Numerische Funktionen
abs( field )
ceil( field )
floor( field )
round( field, decimals )
div( field1, field2 )
mod( field1, field2 )
// Datums-/Zeitfunktionen
dats_days_between( date1, date2 )
dats_add_days( date, days )
dats_add_months( date, months )
$session.system_date
$session.user
$session.client
// Konvertierungen
cast( field as type )
currency_conversion( ... )
unit_conversion( ... )
// Null-Behandlung
coalesce( field, default )

Best Practices

// 1. Sinnvolle Feldnamen (CamelCase)
@AbapCatalog.sqlViewName: 'ZSQLSALES'
define view Z_I_SalesOrders
as select from vbak
{
key vbeln as SalesOrderId, // Nicht: VBELN
kunnr as CustomerId, // Nicht: KUNNR
erdat as CreationDate // Nicht: ERDAT
}
// 2. Annotationen für Semantik
{
@Semantics.amount.currencyCode: 'Currency'
netwr as NetAmount,
@Semantics.currencyCode: true
waerk as Currency,
@Semantics.quantity.unitOfMeasure: 'Unit'
kwmeng as Quantity,
@Semantics.unitOfMeasure: true
vrkme as Unit
}
// 3. Kardinalitäten bei Assoziationen
association [1..1] to ... // Genau eine
association [0..1] to ... // Null oder eine
association [0..*] to ... // Null bis viele
association [1..*] to ... // Eine bis viele

Wichtige Hinweise / Best Practice

  • CDS Views sind die Grundlage für moderne SAP-Entwicklung (Fiori, RAP).
  • Nutzen Sie Interface Views (I_) für wiederverwendbare Basismodelle.
  • Nutzen Sie Consumption Views (C_) für UI-spezifische Anforderungen.
  • Assoziationen statt JOINs für flexiblere, performantere Abfragen.
  • Annotationen steuern Verhalten, UI und Berechtigungen.
  • @AccessControl.authorizationCheck für Berechtigungsprüfung aktivieren.
  • CDS Views können in ABAP wie normale Tabellen in SELECT verwendet werden.
  • HANA-Optimierung: Berechnungen werden auf die Datenbank gepusht.
  • Verwenden Sie Parameter für flexible, wiederverwendbare Views.
  • Virtual Data Model (VDM): Folgen Sie SAP-Namenskonventionen für konsistente Modelle.