Getting Started with SAP ABAP Core Data Services (CDS)
Emre Göçmen
Author

ABAP Core Data Services (CDS) - Comprehensive Guide
Table of Contents
- What is CDS?
- Advantages of ABAP CDS
- Creating CDS Views
- CDS Associations
- Creating OData Service with CDS
- CDS Analytical Queries
- Performance Optimization
- Conclusion
1. What is CDS?
Core Data Services (CDS) is a powerful framework developed by SAP for data modeling and data access that leverages the capabilities of SAP HANA. CDS extends traditional SQL VIEWs to allow for richer semantic modeling.
CDS is one of the foundational building blocks of SAP S/4HANA architecture and is used for:
- Data modeling
- Data access
- Integration of business logic into data models
- User Interface (UI) bindings
- Analytics operations
- Service-based data consumption (OData)
ABAP CDS enables using this concept in the ABAP development environment, supporting SAP HANA's "Code-to-Data" principle - bringing code to the database for processing data, thus reducing network traffic and increasing performance.
2. Advantages of ABAP CDS
- Database-Level Processing: Data processing operations are performed at the database layer, providing significant performance improvements compared to operations at the ABAP layer.
- Reusability: CDS views are defined centrally and can be reused by multiple applications, reports, and interfaces, reducing code duplication.
- Rich Data Modeling: Supports powerful features such as calculated fields, associations, parameters, and more.
- Code Consistency: When data access logic is centralized in CDS views, all applications follow the same business rules.
- Comprehensive Annotation Support: You can add semantic enrichments for UI rendering, OData services, search support, and more.
- SAP Fiori Integration: CDS views can be used to define data sources for SAP Fiori applications.
- Analytical Capabilities: Includes aggregation and drill-down capabilities for analytical querying.
- Authorization Control: Data access control can be defined directly at the CDS level.
3. Creating CDS Views
3.1 Basic CDS View
Follow these steps to create a CDS view using ABAP Development Tools (ADT):
Step 1: Open your project in Eclipse-based ABAP Development Tools (ADT) or SAP Business Application Studio.
Step 2: Create a new CDS view:
- Right-click on your project > New > ABAP Repository Object > Core Data Services > Data Definition
Step 3: Name your CDS view (e.g., Z_CUSTOMER_BASIC) and define it as follows:
@AbapCatalog.sqlViewName: 'ZCUSTOMERBASIC'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Customer Basic Data'
define view Z_CUSTOMER_BASIC
as select from kna1
{
key kna1.kunnr as CustomerNumber,
kna1.name1 as CustomerName,
kna1.land1 as CountryCode,
kna1.ort01 as City,
kna1.pstlz as PostalCode,
kna1.stras as Street,
kna1.telf1 as Telephone,
kna1.kunnr as SearchTerm
}
where kna1.loevm = '' // Select only those not marked as deleted
Annotations:
- @AbapCatalog.sqlViewName: Specifies the name of the physical SQL view to be created in the database. Must be maximum 16 characters.
- @AbapCatalog.compiler.compareFilter: Used for better optimization of SQL WHERE clauses.
- @AccessControl.authorizationCheck: Defines the authorization check level. The value
#CHECKindicates that standard SAP authorization checks will be applied. - @EndUserText.label: Provides a descriptive label for the view.
3.2 Using Annotations
Annotations are metadata that enrich CDS views for various consumption scenarios. Here's an example with more advanced annotations:
@AbapCatalog.sqlViewName: 'ZCUSTUI'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Customer Data with UI Customization'
@UI: {
headerInfo: {
typeName: 'Customer',
typeNamePlural: 'Customers',
title: { type: #STANDARD, value: 'CustomerName' }
}
}
@Search.searchable: true
define view Z_CUSTOMER_UI
as select from kna1
{
@UI.facet: [
{ id: 'CustomerDetails',
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'Customer Details',
position: 10 }
]
@UI.hidden: true
key kna1.kunnr as CustomerNumber,
@UI: {
lineItem: [{ position: 10, importance: #HIGH }],
identification: [{ position: 10 }],
selectionField: [{ position: 10 }]
}
@Search.defaultSearchElement: true
kna1.name1 as CustomerName,
@UI: {
lineItem: [{ position: 20, importance: #MEDIUM }],
identification: [{ position: 20 }],
selectionField: [{ position: 20 }]
}
@Consumption.valueHelp: '_Country'
kna1.land1 as CountryCode,
@UI: {
lineItem: [{ position: 30, importance: #MEDIUM }],
identification: [{ position: 30 }]
}
kna1.ort01 as City,
@UI: {
identification: [{ position: 40 }]
}
kna1.pstlz as PostalCode,
@UI: {
identification: [{ position: 50 }]
}
kna1.stras as Street,
@UI: {
identification: [{ position: 60 }]
}
kna1.telf1 as Telephone
}
where kna1.loevm = ''
Important UI Annotations:
- @UI.headerInfo: Defines header information in list used in Fiori elements.
- @UI.facet: Defines UI sections and layout.
- @UI.lineItem: Specifies which fields should be shown in the list view.
- @UI.identification: Defines fields shown in the object's detail page.
- @UI.selectionField: Defines fields to appear in search criteria.
- @Search.searchable and @Search.defaultSearchElement: Used for search functionality.
3.3 Parameters and Calculated Fields
CDS views can include calculated fields and parameters, allowing you to create dynamic queries:
@AbapCatalog.sqlViewName: 'ZSALESANALYSIS'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Sales Analysis'
define view Z_SALES_ANALYSIS
with parameters
P_DisplayCurrency : waers,
P_StartDate : sy-datum,
P_EndDate : sy-datum
as select from vbak
inner join vbap on vbak.vbeln = vbap.vbeln
inner join mara on vbap.matnr = mara.matnr
{
key vbak.vbeln as SalesDocument,
key vbap.posnr as SalesDocumentItem,
vbak.audat as DocumentDate,
vbak.kunnr as CustomerNumber,
mara.matnr as MaterialNumber,
mara.mtart as MaterialType,
vbap.kwmeng as OrderQuantity,
vbap.meins as SalesUnit,
// Calculated fields
case when vbap.kwmeng > 0 and vbap.netwr > 0
then division(vbap.netwr, vbap.kwmeng, 2)
else 0
end as UnitPrice,
vbap.netwr as NetAmount,
// Currency conversion (example - real conversion is more complex)
currency_conversion(
amount => vbap.netwr,
source_currency => vbak.waerk,
target_currency => :P_DisplayCurrency,
exchange_rate_date => vbak.audat
) as ConvertedAmount,
// Using HANA's SQL functions
days_between(vbak.audat, vbak.erdat) as DaysToProcessing
}
where vbak.audat between :P_StartDate and :P_EndDate
and vbak.vbtyp = 'C' // Select only orders
Parameters and Calculated Fields Explanation:
- with parameters: Defines input parameters for dynamic filters and calculations.
- Calculated fields: You can use
CASEstatements, functions, and other SQL expressions. - currency_conversion(): SAP's currency conversion function.
- days_between(): SAP HANA's function to calculate days between dates.
4. CDS Associations
CDS associations allow you to establish connections between CDS views and pre-join data:
@AbapCatalog.sqlViewName: 'ZCUSTORDERS'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Customer with Orders'
define view Z_CUSTOMER_ORDERS
as select from Z_CUSTOMER_BASIC as Customer
association [0..*] to vbak as _SalesOrders
on Customer.CustomerNumber = _SalesOrders.kunnr
association [0..1] to t005t as _CountryText
on $projection.CountryCode = _CountryText.land1
and _CountryText.spras = 'E' // Language code for English
{
key Customer.CustomerNumber,
Customer.CustomerName,
Customer.CountryCode,
_CountryText.landx as CountryName,
Customer.City,
Customer.PostalCode,
// Counting orders (cardinality semantics)
@Semantics.amount.currencyCode: 'OrdersCurrencyCode'
_SalesOrders.netwr as TotalOrdersAmount,
_SalesOrders.waerk as OrdersCurrencyCode,
// Exposing associations
_SalesOrders,
_CountryText
}
Explanation of the Above Code:
- association [0..*]: Defines a one-to-many relationship between customer and orders.
- association [0..1]: Defines a one-to-one relationship between country code and country description.
- on $projection.CountryCode: Join conditions are defined using fields from the current projection.
- _SalesOrders: Alias used to access the association.
Using Associations:
After defining associations, you can create another CDS view that uses these associations:
@AbapCatalog.sqlViewName: 'ZCUSTORDDETAIL'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Customer Order Details'
define view Z_CUSTOMER_ORDER_DETAILS
as select from Z_CUSTOMER_ORDERS as CustomerOrders
association [1..*] to vbap as _OrderItems
on CustomerOrders._SalesOrders.vbeln = _OrderItems.vbeln
{
key CustomerOrders.CustomerNumber,
CustomerOrders.CustomerName,
key CustomerOrders._SalesOrders.vbeln as SalesDocument,
key _OrderItems.posnr as SalesDocumentItem,
_OrderItems.matnr as MaterialNumber,
_OrderItems.arktx as ItemDescription,
@Semantics.quantity.unitOfMeasure: 'OrderUnit'
_OrderItems.kwmeng as OrderQuantity,
_OrderItems.meins as OrderUnit,
@Semantics.amount.currencyCode: 'DocumentCurrency'
_OrderItems.netwr as NetAmount,
_OrderItems.waerk as DocumentCurrency
}
Important points about associations:
- Associations are only defined, they don't automatically fetch data
- When you want to use associated data, explicitly add it to the projection or expose it
- Associations are more flexible and intuitive than using JOINs in CDS views
- They work with LEFT OUTER JOIN semantics
5. Creating OData Service with CDS
You can easily publish CDS views as OData services that can be consumed by SAP Gateway:
Step 1: Add OData Annotations to CDS View
@AbapCatalog.sqlViewName: 'ZCUSTODATA'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Customer OData Service'
@OData.publish: true
@ObjectModel.modelCategory: #BUSINESS_OBJECT
@ObjectModel.compositionRoot: true
@ObjectModel.transactionalProcessingEnabled: true
@ObjectModel.writeActivePersistence: 'kna1'
@ObjectModel.createEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.deleteEnabled: true
define view Z_CUSTOMER_ODATA
as select from kna1
{
@ObjectModel.mandatory: true
key kna1.kunnr as CustomerNumber,
@ObjectModel.mandatory: true
kna1.name1 as CustomerName,
kna1.land1 as CountryCode,
kna1.ort01 as City,
kna1.pstlz as PostalCode,
kna1.stras as Street,
kna1.telf1 as Telephone
}
where kna1.loevm = ''
OData Annotation Explanation:
- @OData.publish: Publishes the view as an OData service.
- @ObjectModel.modelCategory: Defines it as a business object model.
- @ObjectModel.transactionalProcessingEnabled: Enables CRUD (Create, Read, Update, Delete) operations.
- @ObjectModel.writeActivePersistence: The table where write operations will be performed.
- @ObjectModel.xxxEnabled: Enables/disables CRUD operations individually.
Step 2: Create Service Definition
In S/4HANA, you need to create an OData service definition and configuration for SAP Gateway:
@EndUserText.label: 'Customer OData Service'
define service Z_CUSTOMER_SRV {
expose Z_CUSTOMER_ODATA as Customer;
}
Step 3: Activate OData Service
- Run transaction
/IWFND/MAINT_SERVICE - Click on Add Service
- Select the System Alias
- Search for Technical Service Name (Z_CUSTOMER_SRV)
- Activate the service and save
Step 4: Test the Service
You can test your service with the following URL:
https://<server>:<port>/sap/opu/odata/sap/Z_CUSTOMER_SRV/
The OData service can support:
- CRUD operations
- Filtering
- Sorting
- Pagination
- Authorization control
6. CDS Analytical Queries
CDS analytical queries support OLAP capabilities for multidimensional reporting:
@AbapCatalog.sqlViewName: 'ZSALESANAL'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Sales Analytics'
@Analytics.dataCategory: #CUBE
define view Z_SALES_ANALYTICS
as select from vbak
inner join vbap on vbak.vbeln = vbap.vbeln
inner join kna1 on vbak.kunnr = kna1.kunnr
{
// Dimensions
@AnalyticsDetails.query.axis: #FREE
key vbak.vkorg as SalesOrg,
@AnalyticsDetails.query.axis: #FREE
key vbak.vtweg as DistChannel,
@AnalyticsDetails.query.axis: #FREE
key kna1.land1 as CustomerCountry,
@AnalyticsDetails.query.axis: #FREE
key vbap.matnr as Material,
// Date dimension
@AnalyticsDetails.query.axis: #FREE
key vbak.audat as DocDate,
// Measures / Counters
@DefaultAggregation: #SUM
@Semantics.amount.currencyCode: 'Currency'
vbap.netwr as NetAmount,
@DefaultAggregation: #SUM
@Semantics.quantity.unitOfMeasure: 'BaseUnit'
vbap.kwmeng as Quantity,
// Currency/unit
@AnalyticsDetails.query.axis: #FREE
vbap.waerk as Currency,
@AnalyticsDetails.query.axis: #FREE
vbap.meins as BaseUnit
}
Important Notes About Analytical Queries:
- @Analytics.dataCategory: Defines the view as a cube.
- @DefaultAggregation: Specifies automatic aggregation behavior.
- @AnalyticsDetails.query.axis: Specifies fields that can be used as dimension/measure.
- @Semantics: Defines currency and unit of measure relationships.
7. Performance Optimization
Best practices for creating efficient CDS views:
- Select Only Necessary Fields: Select what is needed, avoid using "SELECT *".
- Use Appropriate Indexes: Ensure fields in WHERE clauses of your CDS views are properly indexed.
- Optimize WHERE Clauses: Apply filters as early as possible and allow for index/compare filter optimizations.
- Use @AbapCatalog.compiler.compareFilter: true: Enables SAP's filter optimizations.
- JOIN Optimization:
// Instead of this: as select from A inner join B inner join C // Prefer this (allows better optimization): as select from A inner join B on ... inner join C on ... - Use Associations Instead of Nested Views in CDS: Associations are more flexible and generally better optimized.
- Avoid Function Calls in WHERE Clauses: Function calls prevent index usage.
- Be Careful with Aggregations for High-Volume Tables: Use analytical annotations for aggregation performance.
- Code Pushdown: Push code logic to the database instead of moving data to the application server.
- Monitor CDS Query Performance: Use SQL trace and explain plans to analyze performance.
8. Conclusion
ABAP CDS provides a powerful, semantically rich framework for data modeling and access, unlocking the full potential of SAP HANA. When used correctly, it delivers:
- Higher performance - through the Code-to-Data paradigm
- Easier maintenance - with central definition of data models within SAP S/4HANA architecture
- More efficient development - due to reusability and extensibility of data models
- Modern UI integration - via SAP Fiori and UI annotations
- Robust analytical capabilities - with built-in analytical functions
When building CDS views, following the learned best practices will help you to have modular and performant CDS views. Study standard CDS views to understand SAP S/4HANA models and extend them in your applications.
Comments
No comments yet.
Be the first to comment.



