ABAP CDS View Tutorial — From Basics to Real-World Examples
Step-by-step ABAP CDS View tutorial with code examples. Learn to create CDS Views, add associations, annotations, joins, and parameters in SAP S/4HANA.
Prerequisites
Before you start building CDS Views, make sure you have the following in place:
- SAP S/4HANA system — either an on-premise system (at least 1610), a RISE with SAP instance, or the BTP ABAP Environment (Steampunk). Any system running on an ABAP platform 7.50 or higher will work.
- ABAP Development Tools (ADT) — the Eclipse-based IDE is mandatory for CDS development. Classic SE80 does not support CDS Views.
- Basic ABAP knowledge — you should be comfortable with ABAP Dictionary concepts (tables, data elements, domains) and understand SELECT statements.
- Authorization — you need a development user with permissions to create objects in a custom namespace (typically
Z*orY*).
Creating Your First CDS View
In ADT, right-click your package and choose New → Other ABAP Repository Object → Core Data Services → Data Definition. Give it a name like Z_SalesOrder and a description.
ADT generates a skeleton. Replace it with the following code:
@AbapCatalog.sqlViewName: 'ZSALESORDER'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Sales Orders'
define view Z_SalesOrder
as select from vbak
{
key vbeln as SalesOrder,
erdat as CreationDate,
erzet as CreationTime,
ernam as CreatedBy,
auart as SalesOrderType,
vkorg as SalesOrganization,
vtweg as DistributionChannel,
spart as Division,
netwr as NetValue,
waerk as Currency
}
Let us break down what each part does:
@AbapCatalog.sqlViewName— the technical name of the generated SQL view in the database (max 16 characters). Note: this annotation is not needed for CDS View Entities, which are the modern replacement.@AccessControl.authorizationCheck: #CHECK— tells the runtime to apply any associated DCL (Data Control Language) access controls.@EndUserText.label— a human-readable description shown in tools and metadata.as select from vbak— the data source, here the sales order header table VBAK.key vbeln as SalesOrder— field selection with alias. Thekeykeyword marks primary key fields.
Activate the view with Ctrl+F3. You can test it immediately using the Data Preview (F8) in ADT. For a deeper look at how SAP structures its own sales order views, explore I_SalesOrder on CDSee.
Adding Associations
Associations are one of the most powerful CDS features. Unlike joins, they define navigation paths that are only evaluated when the consumer actually accesses them — this is called path expressions or lazy joins.
define view Z_SalesOrder
as select from vbak
association [1..*] to vbap as _Item
on _Item.vbeln = vbak.vbeln
association [0..1] to kna1 as _Customer
on _Customer.kunnr = vbak.kunnr
{
key vbeln as SalesOrder,
kunnr as Customer,
netwr as NetValue,
waerk as Currency,
// Expose associations
_Item,
_Customer
}
The cardinality in square brackets tells the framework how many target records to expect:
[0..1]— zero or one (e.g., an optional master data lookup)[1..1]— exactly one (mandatory 1:1 relationship)[1..*]— one or more (e.g., header to items)[0..*]— zero or more (the most flexible cardinality)
By convention, association names start with an underscore (_Item, _Customer). Associations must be listed in the field list to be exposed to consumers. For a thorough explanation of how SAP uses associations and field mappings in the VDM, read the guide on Field Mapping and Associations.
Adding Annotations
Annotations are the metadata layer that makes CDS Views so versatile. They control everything from analytics behavior to Fiori UI rendering.
VDM Classification
@VDM.viewType: #BASIC
@Analytics.dataCategory: #DIMENSION
The @VDM.viewType annotation classifies the view in SAP's Virtual Data Model: #BASIC, #COMPOSITE, or #CONSUMPTION. See CDS View Types for details.
UI Annotations for Fiori
@UI.headerInfo: {
typeName: 'Sales Order',
typeNamePlural: 'Sales Orders',
title: { value: 'SalesOrder' }
}
@UI.lineItem: [{ position: 10 }]
vbeln as SalesOrder,
@UI.lineItem: [{ position: 20 }]
@UI.selectionField: [{ position: 10 }]
auart as SalesOrderType
These annotations drive Fiori Elements apps — the list page layout, filter bar, object page sections, and more — without writing any frontend code. For a complete reference, see CDS View Annotations.
OData Exposure
The older approach used @OData.publish: true to generate an OData service directly from a CDS View. This is now deprecated. The modern approach is to create a Service Definition and a Service Binding:
// Service Definition
define service Z_SalesOrder_SD {
expose Z_SalesOrder as SalesOrder;
expose Z_SalesOrderItem as SalesOrderItem;
}
You then create a Service Binding in ADT to bind this definition to an OData V2 or V4 protocol. Read more in Service Bindings and Service Definitions.
Working with Joins
While associations are preferred for most scenarios, explicit joins are still useful when you need the joined data in every query execution.
define view Z_SalesOrderWithCustomer
as select from vbak
inner join kna1
on vbak.kunnr = kna1.kunnr
{
key vbak.vbeln as SalesOrder,
kna1.name1 as CustomerName,
kna1.land1 as Country,
vbak.netwr as NetValue,
vbak.waerk as Currency
}
CDS supports inner join, left outer join, right outer join, and cross join. A practical rule of thumb:
- Use associations when the related data is optional or consumed selectively.
- Use joins when you always need the combined result set, especially for flattened analytical views.
Parameters and Filters
CDS Views support input parameters that allow consumers to pass values at runtime:
define view Z_SalesOrderByType
with parameters
p_order_type : auart
as select from vbak
{
key vbeln as SalesOrder,
auart as SalesOrderType,
netwr as NetValue,
waerk as Currency
}
where auart = $parameters.p_order_type
Parameters are useful when a view must always be filtered by a specific value (e.g., company code or fiscal year). You can also use CASE expressions, CAST, and built-in functions like SUBSTRING, CONCAT, and DATS_DAYS_BETWEEN to add calculated fields.
CDS View vs. CDS View Entity
Since S/4HANA 2020, SAP introduced CDS View Entities as the successor to classic CDS Views:
- View Entities use
define view entityinstead ofdefine view. - No
@AbapCatalog.sqlViewNameneeded — no SQL view is generated in the database dictionary. - Stricter type system and better performance in some scenarios.
- Associations with
redirected tofor cleaner composition models.
For new development, SAP recommends CDS View Entities. However, classic CDS Views remain fully supported and are still used extensively in the standard S/4HANA codebase.
Learning from SAP's CDS Views
One of the best ways to improve your CDS skills is to study how SAP builds its own views. CDSee makes this easy:
- Start with a well-known view — open I_SalesOrder and look at the schema representation.
- Trace the data lineage — click through the base views to understand the layered architecture.
- Study basic views — browse all Basic Views to see how SAP models its foundation layer.
- Examine the annotations — pay attention to which annotations SAP uses on analytical vs. transactional views.
- Check released APIs — when building extensions, always check whether a view is released. See Released APIs.