What are CDS Views in SAP?
If you have asked what is CDS views while working on S/4HANA, ABAP Cloud, or anything built on SAP HANA, the short answer is: CDS (Core Data Services) is SAP's data modeling layer. A CDS view is a SQL-like definition that runs on the database, lets you compute joins, aggregations, and projections close to the data instead of pulling rows into the application server, and is decorated with metadata that makes it consumable by Fiori apps, OData services, and analytics tools. ABAP CDS views are the dominant form and the foundation of modern ABAP development.
This guide covers what CDS views are, the difference between classic CDS views and CDS view entities, the anatomy of a view, annotations, associations, and how to query CDS from ABAP and the RESTful Application Programming Model (RAP).
What Are CDS Views?
A CDS view is a data modeling artifact written in DDL (Data Definition Language) with SAP extensions. You define what columns to select, how to join and aggregate, and how to decorate the result with metadata. The database compiles the definition into an optimized SQL or calculation view, and the result is a reusable, semantically rich data model that Fiori apps, OData services, analytical applications, and ABAP programs can consume.
The defining idea is code pushdown. Instead of reading large volumes of data into the ABAP application server and processing it there (which is slow and does not scale), you push the computation down to the HANA in-memory database, where the work happens on columnar, in-memory structures. CDS views are the primary mechanism for that pushdown in the ABAP world.
CDS views are more than SQL because of annotations. Plain SQL describes the shape of the result; CDS annotations describe what the result means: which column is an amount with a currency, which is the representative key of a dimension, which fields the UI should show, and whether the view should be exposed as an OData service. That metadata is what lets a single CDS view power a Fiori Elements app, an analytical model, and an ABAP report without duplication.
CDS View Entity vs Classic CDS View
This is the change most teams hit first. There are two forms of ABAP CDS view, and the one you pick matters for ABAP Cloud compatibility:
| Aspect | CDS View Entity (new) | Classic CDS View (legacy) |
|---|---|---|
| Definition syntax | define view entity | define view |
| DDIC dependency | None (DDIC-independent) | Generates a DDIC SQL view |
| Generated objects | Only the entity | DDIC SQL view + entity |
| ABAP Cloud ready | Yes (preferred form) | Deprecated for new dev |
| Comparison annotation | Not needed | @AbapCatalog.compilerCompare |
| Naming in ABAP SQL | Use entity name directly | Use entity or DDIC view name |
SAP's guidance is unambiguous: all new development should use CDS view entities
(define view entity). Classic CDS views (define view) are still supported for
compatibility with existing systems, but they are on the deprecation path for ABAP Cloud
and will not pass cloud-readiness checks for new code. If you are maintaining an older
codebase you will see both; if you are starting fresh, only use view entities.
The practical impact is small for most authoring tasks (the select from, joins, and
annotations are nearly identical), but the tooling, transport, and release-contract
behavior differ. Use view entities unless you have a specific reason not to.
Anatomy of a CDS View
A complete ABAP CDS view entity looks like this. This example selects customer orders, joins to a customer dimension, exposes an association to order items, and carries the annotations a Fiori Elements app or analytic model would need:
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Customer Orders'
@Metadata.allowExtensions: true
define view entity ZI_CustomerOrder
as select from zsales_order_hdr as Header
association [0..1] to zcustomer as _Customer
on $projection.CustomerID = _Customer.CustomerID
association [1..*] to zsales_order_itm as _Items
on $projection.OrderID = _Items.OrderID
{
key Header.OrderID as OrderID,
key Header.ItemCount as ItemSeq,
Header.CustomerID as CustomerID,
_Customer.CustomerName as CustomerName,
_Customer.Region as Region,
Header.OrderDate as OrderDate,
@Semantics.amount.currencyCode: 'Currency'
Header.NetAmount as NetAmount,
Header.Currency as Currency,
@Semantics.quantity.unitOfMeasure: 'Unit'
Header.Quantity as Quantity,
Header.Unit as Unit,
_Customer,
_Items
}
Reading this from top to bottom:
- Header annotations (
@AccessControl.authorizationCheck,@EndUserText.label) apply to the whole view.#CHECKmeans the framework verifies that a matching DCL (Data Control Language) access control exists at activation time. define view entitydeclares the new-style view entity.as select fromnames the source table and assigns an alias.associationlines declare relationships with cardinality and anONcondition. These are not joins yet; they are reusable paths consumers can follow.- The field list maps source columns to output fields, with field-level annotations
like
@Semantics.amount(ties an amount to its currency code column) and@Semantics.quantity(ties a quantity to its unit). _Customerand_Itemsin the field list expose the associations so consumers can navigate them with path expressions.
The view compiles into an optimized database object. Querying it from ABAP, exposing it as OData, or using it as the source for another view all work without redefining the logic.
Key Annotations
CDS annotations are what turn SQL into a semantic model. There are hundreds of annotations organized by prefix; the ones you will reach for most often are:
| Annotation | Purpose |
|---|---|
@EndUserText.label | Human-readable label for the view or a field |
@AccessControl.authorizationCheck | Enables DCL-based authorization (#CHECK, #NOT_REQUIRED, #PRIVILEGED_ONLY) |
@ObjectModel.representativeKey | Marks the representative key of a dimension for analytics |
@ObjectModel.semanticKey | Declares the business key (may differ from technical key) |
@Semantics.amount | Tags a field as a currency amount, with currencyCode pointing to the currency column |
@Semantics.quantity | Tags a field as a quantity, with unitOfMeasure pointing to the unit column |
@Semantics.calendar.* | Tags date fields as calendar year, month, day, etc. |
@OData.publish: true | Exposes the view as an OData service automatically |
@UI.* | Drives Fiori Elements rendering (line items, selection fields, identification) |
@AnalyticsDetails.* | Controls analytical behavior and aggregation |
@Consumption.filter.* | Declares mandatory or default filter values for consumption |
@Metadata.allowExtensions | Allows the view to be extended with extend view entity |
@AbapCatalog.compilerCompare | Controls DDIC view comparison (classic views only) |
Annotation mistakes are the most common reason a CDS view compiles but behaves wrong at
runtime. The @Semantics.amount / currencyCode pair, for example, is what makes SAP
Analytics Cloud and Fiori render currency correctly; miss it and your amounts show
without a currency or aggregate incorrectly.
Associations and Compositions
Associations are CDS's way of modeling relationships. An association has a target
view, a cardinality, and an ON condition. Unlike a join, an association does not
duplicate rows when you expose it; it is a navigable path that consumers follow only
when they need the related data.
Cardinality is written as [min..max] on the source side:
[0..1]to-one: at most one target row matches (a header to its customer).[1..1]to-one: exactly one target row matches (a header to its mandatory customer).[1..*]to-many: one or more target rows match (a header to its items).[0..*]to-many: zero or more target rows match.
association [1..*] to zsales_order_itm as _Items
on $projection.OrderID = _Items.OrderID
You expose the association by listing it in the field list (_Items). Consumers then
navigate it with path expressions: _Items.NetAmount, _Items._Product.ProductName.
When the consumer needs the data, the framework turns the path into a join at query time.
Compositions are a stronger form used for parent-child, document-style relationships where the child cannot exist without the parent (order header to order items, for example). Compositions are central to RAP, where they define the deep structure of a business object and enable draft handling and deep create/update.
Querying CDS from ABAP
Once a CDS view entity is active, you query it from ABAP with ABAP SQL (formerly Open SQL). The syntax is SQL-like and supports the CDS features directly, including associations and parameters.
A basic read against the view from the previous example:
SELECT OrderID,
CustomerID,
CustomerName,
NetAmount,
Currency
FROM ZI_CustomerOrder
WHERE OrderDate >= @iv_from_date
INTO TABLE @DATA(lt_orders).
You can navigate associations directly in ABAP SQL using the path expression with the tilde:
SELECT Header~OrderID,
Header~_Items~ProductID AS ProductID,
Header~_Items~NetAmount AS ItemNet
FROM ZI_CustomerOrder AS Header
WHERE Header~Region = 'EMEA'
INTO TABLE @DATA(lt_detail).
For a parameterized view (one declared with parameters), you pass the values in the
WITH PARAMETERS clause:
SELECT *
FROM ZI_CustomerOrder( p_fiscalyear: '2026' )
INTO TABLE @DATA(lt_orders).
Because the aggregation and join logic lives in the CDS view, the ABAP code stays short. The database does the heavy lifting, which is exactly the code-pushdown principle in action.
CDS in the RESTful Application Programming Model (RAP)
CDS views are the data model layer in the RESTful Application Programming Model (RAP). A RAP business object is built from a hierarchy of CDS views:
- Interface views (
ZI_*) model the data and the composition tree. They expose associations and carry the semantic annotations. - Consumption views (
ZC_*) project the interface views for a specific service, adding consumption annotations (@UI.*,@Consumption.*) and authorization. - Behavior definitions (BDEF) sit on top of the interface views and declare the operations (create, update, delete, actions, determinations, validations) that the business object supports.
The OData service that a Fiori app consumes is generated from the projection view and behavior definition. This layered approach keeps the data model reusable: one interface view can feed many consumption views, each tailored to a specific UI or API, without duplicating the underlying logic.
CDS Views with AI Coding Assistants
CDS syntax is SAP-specific and unforgiving. The annotation vocabulary has hundreds of
entries across @ObjectModel, @Analytics, @Consumption, @UI, @Metadata,
@Semantics, and more, and the rules differ between classic ABAP CDS, ABAP CDS view
entities, and ABAP Cloud-restricted views. General-purpose AI assistants frequently:
- Mix ABAP CDS syntax with HANA CDS or plain SQL.
- Suggest deprecated annotations or the wrong view type (
define viewinstead ofdefine view entity). - Produce views that compile but violate ABAP Cloud release contracts.
- Get cardinality, path expressions,
$projection, and$parameterswrong.
The sap-abap-cds skill gives an AI assistant a curated reference for the full
annotation catalog, association and cardinality syntax, DCL access control, built-in
functions, and the patterns that align with ABAP Cloud. Install it to bring accurate
CDS context into your editor:
npx skills add secondsky/sap-skills --skill sap-abap-cds
Pair it with the core sap-abap skill for general ABAP context, and with
sap-fiori-tools when you are exposing CDS views through Fiori Elements. With the
right skills loaded, an assistant can draft correctly annotated view entities, suggest
the right VDM tier, and flag annotations that will not pass cloud-readiness checks.
Note: SAP Skills is a community-maintained, open-source collection of plugins for AI coding assistants. It is not an official SAP product and is not affiliated with or endorsed by SAP SE. The skills encode publicly documented SAP knowledge to help AI assistants produce more accurate SAP code.