Appearance
Lesson 2 — Introduction to ABAP CDS
In Lesson 1, the application architecture was:
text
Runner
↓
Reader
↓
ABAP SQL
↓
Database TableThe Reader accessed /DMO/CARRIER directly.
In this lesson, you will introduce a reusable CDS data-modeling layer:
text
Runner
↓
Reader
↓
ABAP SQL
↓
CDS View Entity
↓
Database TableYou will create a CDS View Entity over /DMO/CARRIER, inspect it with Data Preview, query it with SQL Console, and then change the Reader so that it reads the CDS entity instead of the database table.
The Runner will keep the same responsibility: it calls the Reader and displays the returned data.
Lesson information
| Duration | About 90–120 minutes |
| Environment | SAP BTP ABAP Trial |
| Development tool | Eclipse with ABAP Development Tools (ADT) |
| Prerequisites | Lesson 1, ABAP OOP, basic ABAP SQL |
| Persistence source | /DMO/CARRIER |
| CDS entity | ZI_CARRIER_### |
| Reader | ZCL_CARRIER_READER_### |
| Runner | ZCL_SQL_L01_### |
Learning objectives
After completing this lesson, you should be able to:
- explain what ABAP Core Data Services (CDS) is;
- explain why a reusable data-modeling layer is useful;
- distinguish a database table, Data Definition, CDS View Entity, Reader, and Runner;
- create a Data Definition in ADT;
- write a CDS View Entity with
define view entity; - identify the CDS data source;
- use a source alias;
- expose selected elements;
- rename source fields with CDS aliases;
- define a CDS key element;
- activate a Data Definition;
- use CDS Data Preview;
- query a CDS View Entity in SQL Console;
- consume a CDS View Entity with ABAP SQL;
- update the Reader so that callers remain insulated from a change in its data source.
Starting architecture
From Lesson 1:
text
┌────────────────────────────┐
│ ZCL_SQL_L01_### │
│ Runner │
└──────────────┬─────────────┘
│ calls
▼
┌────────────────────────────┐
│ ZCL_CARRIER_READER_### │
│ Reader │
└──────────────┬─────────────┘
│ ABAP SQL
▼
┌────────────────────────────┐
│ /DMO/CARRIER │
│ Database table │
└────────────────────────────┘At the end of Lesson 2:
text
┌────────────────────────────┐
│ ZCL_SQL_L01_### │
│ Runner │
└──────────────┬─────────────┘
│ calls
▼
┌────────────────────────────┐
│ ZCL_CARRIER_READER_### │
│ Reader │
└──────────────┬─────────────┘
│ ABAP SQL
▼
┌────────────────────────────┐
│ ZI_CARRIER_### │
│ CDS View Entity │
└──────────────┬─────────────┘
│ selects from
▼
┌────────────────────────────┐
│ /DMO/CARRIER │
│ Database table │
└────────────────────────────┘Before you start
You should have the objects created in Lesson 1:
text
ZCL_CARRIER_READER_###
ZCL_SQL_L01_###The Reader should already contain methods similar to:
text
GET_ALL
GET_BY_CURRENCY
GET_BY_IDReplace ###
Use your own student/group suffix.
Example:
text
ZI_CARRIER_### → ZI_CARRIER_017The object name must be unique in the shared training system.
ABAP Cloud and /DMO/*
The /DMO/* objects used in these lessons belong to SAP's ABAP Flight Reference Scenario and are SAP demo/tutorial content.
They are being used deliberately for training.
In productive ABAP Cloud development, SAP-delivered functionality should be consumed through APIs that are released for the applicable cloud-development contract.
1. Why introduce CDS?
In Lesson 1, the Reader contains SQL such as:
abap
SELECT FROM /dmo/carrier
FIELDS carrier_id,
name,
currency_code
ORDER BY carrier_id
INTO TABLE @carriers.This works.
But the Reader is coupled directly to the persistence model:
text
Reader
↓
/DMO/CARRIERImagine that several consumers need the same business-oriented representation of carrier data.
They may all need:
text
CarrierId
Name
CurrencyCoderather than depending directly on persistence-oriented names:
text
carrier_id
name
currency_codeA reusable data model gives those consumers one shared definition.
text
Persistence
↓
Reusable CDS model
↓
ConsumersMain idea
A database table stores persistent data.
A CDS View Entity defines a reusable data model over data sources.
2. What does CDS mean?
CDS stands for:
Core Data Services
ABAP CDS is used to define data models in the ABAP platform.
A CDS View Entity can:
- select data from one or more data sources;
- expose selected elements;
- rename elements;
- model relationships;
- define calculations and expressions;
- carry semantic metadata through annotations.
This lesson uses only the first layer of those capabilities:
text
one source
selected elements
aliases
key
basic annotationsJoins, associations, richer expressions, and semantic annotations are covered in later lessons.
3. CDS View Entities
The modern CDS entity type used in this course is:
abap
define view entityExample:
abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Carrier'
define view entity ZI_Carrier_###
as select from /dmo/carrier as Carrier
{
key Carrier.carrier_id as CarrierId,
Carrier.name as Name,
Carrier.currency_code as CurrencyCode
}Modern ABAP CDS
CDS View Entities are the modern successor to older DDIC-based CDS views.
New course examples use:
abap
define view entityrather than the older:
abap
define view4. Data Definition vs CDS View Entity
These terms are related, but they are not identical.
Data Definition
A Data Definition is an ABAP repository object.
You create it in ADT.
It contains CDS DDL source code and participates in normal repository functions such as:
text
syntax check
activation
transport
where-usedCDS View Entity
The CDS source inside the Data Definition defines the CDS View Entity.
Think of it like this:
text
Data Definition
│
│ contains CDS source
▼
define view entity ...
│
│ defines
▼
CDS View EntityAfter activation, the CDS View Entity can be consumed by ABAP SQL and by other supported CDS scenarios.
5. Our first CDS model
We will model:
text
/DMO/CARRIERThe persistence fields are:
text
carrier_id
name
currency_codeThe CDS entity will expose:
text
CarrierId
Name
CurrencyCodeThe complete first definition is:
abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Carrier'
define view entity ZI_Carrier_###
as select from /dmo/carrier as Carrier
{
key Carrier.carrier_id as CarrierId,
Carrier.name as Name,
Carrier.currency_code as CurrencyCode
}Before creating the object, examine each part.
6. Header annotations
The first two lines are annotations:
abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Carrier'Annotations add metadata to CDS objects and elements.
@EndUserText.label
abap
@EndUserText.label: 'Carrier'provides a readable label.
@AccessControl.authorizationCheck
abap
@AccessControl.authorizationCheck: #NOT_REQUIREDstates that this CDS entity does not require a CDS access-control check.
This training entity does not define CDS access control.
INFO
Authorization modeling with CDS roles is a separate topic.
#NOT_REQUIRED here describes this specific tutorial entity; it is not a universal setting for every CDS entity.
7. define view entity
abap
define view entity ZI_Carrier_###This defines a CDS View Entity.
The entity name is:
text
ZI_CARRIER_###Naming
ZI_ is the naming convention used by this course for an interface-style CDS entity.
It is not a CDS keyword.
Projects should follow their own agreed naming conventions.
8. as select from
abap
as select from /dmo/carrier as CarrierThe data source is:
text
/DMO/CARRIERThe source alias is:
text
CarrierThat alias lets the element list clearly identify the source:
abap
Carrier.carrier_id
Carrier.name
Carrier.currency_codeSource aliases become especially useful when a CDS entity later uses multiple data sources or associations.
9. The element list
The braces contain the elements exposed by the CDS entity:
abap
{
key Carrier.carrier_id as CarrierId,
Carrier.name as Name,
Carrier.currency_code as CurrencyCode
}The CDS entity does not have to expose every column from the underlying source.
It exposes exactly the model defined in the element list.
CDS View Entities and *
A CDS View Entity element list does not use * to expose every source field.
List the elements that belong to the model explicitly.
10. CDS element aliases
This element:
abap
Carrier.carrier_id as CarrierIdhas:
text
Source field: carrier_id
CDS element: CarrierIdLikewise:
abap
Carrier.currency_code as CurrencyCodeexposes:
text
currency_code → CurrencyCodeThe CDS model therefore presents its own element names independently of the persistence names.
11. CDS key
This element is marked:
abap
key Carrier.carrier_id as CarrierIdCarrierId is the key element of this CDS entity.
In /DMO/CARRIER, carrier_id identifies the persisted carrier record, so it is appropriate to expose it as the key of this model.
CDS key semantics
The CDS key describes the key of the CDS entity.
It does not create a new database uniqueness constraint.
The actual persisted uniqueness in this example comes from the key of /DMO/CARRIER.
12. Create the Data Definition in ADT
Now create the repository object.
Step 12.1 — Select your package
In Project Explorer:
- Expand your ABAP Cloud Project.
- Find your assigned package.
- Right-click the package.
Do not create your object in a /DMO/ package.
Step 12.2 — Open the repository-object wizard
Choose:
text
New
→ Other ABAP Repository ObjectThen select:
text
Core Data Services
→ Data DefinitionChoose Next.
Step 12.3 — Enter the object details
Enter:
Name
text
ZI_CARRIER_###Description
text
Lesson 2 - Carrier CDSIf your ADT wizard provides a Referenced Object field, enter:
text
/DMO/CARRIERThe referenced object can help ADT generate a useful starting point.
Choose Next.
Step 12.4 — Assign the transport
If the training system asks for a transport request:
- choose the request assigned for the course;
- continue to the template page.
The exact transport screen depends on the training-system setup.
Step 12.5 — Choose a View Entity template
Select the template for a CDS View Entity.
Template wording can vary between ADT/backend versions.
The generated source for this course should use:
abap
define view entityDo not choose a template that generates the obsolete DDIC-based:
abap
define viewChoose Finish.
ADT creates the inactive Data Definition and opens the CDS source editor.
13. Enter the CDS source
Replace or adjust the generated source so that it becomes:
abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Carrier'
define view entity ZI_Carrier_###
as select from /dmo/carrier as Carrier
{
key Carrier.carrier_id as CarrierId,
Carrier.name as Name,
Carrier.currency_code as CurrencyCode
}Replace ###.
Example:
abap
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Carrier'
define view entity ZI_Carrier_017
as select from /dmo/carrier as Carrier
{
key Carrier.carrier_id as CarrierId,
Carrier.name as Name,
Carrier.currency_code as CurrencyCode
}14. Use CDS code completion
ADT provides context-sensitive code completion in the CDS editor.
Try it.
Step 14.1 — Complete a source field
Place the cursor after:
abap
Carrier.Press:
text
Ctrl + SpaceADT should offer fields from the source.
Choose the required element.
Step 14.2 — Inspect help
You can also use ADT help/navigation features on CDS keywords, annotations, and elements.
This is useful when you encounter unfamiliar CDS syntax later in the course.
15. Syntax check
Before activation, run a syntax check.
Press:
text
Ctrl + F2Check the Problems view if ADT reports errors.
Common first errors are:
text
incorrect object name
missing comma
misspelled source field
missing closing brace
wrong source aliasFix the errors before activation.
16. Activate the Data Definition
Press:
text
Ctrl + F3Activation creates the active CDS entity in the backend.
Checkpoint
At this point:
text
/DMO/CARRIERstill stores the data.
You have added:
text
ZI_CARRIER_###as a reusable model over that data.
17. Open CDS Data Preview
Place the cursor inside the CDS source and press:
text
F8You can also use:
text
Open With
→ Data PreviewThe preview should expose:
text
CarrierId
Name
CurrencyCodeCompare this with the persistence table:
text
/DMO/CARRIER
carrier_id
name
currency_codeThe records come from the underlying source, while the CDS entity defines the exposed model.
18. Verify that the CDS model controls exposure
Temporarily remove:
abap
Carrier.currency_code as CurrencyCodeso the element list becomes:
abap
{
key Carrier.carrier_id as CarrierId,
Carrier.name as Name
}Activate again:
text
Ctrl + F3Open Data Preview again.
You should now see:
text
CarrierId
NameThe database table has not changed.
The CDS model has changed.
Restore:
abap
Carrier.currency_code as CurrencyCodeand activate again.
19. Query the CDS entity in SQL Console
Lesson 1 introduced SQL Console.
Open SQL Console from your ABAP project or from a relevant ADT context.
Run:
abap
SELECT FROM zi_carrier_###
FIELDS CarrierId,
Name,
CurrencyCode
ORDER BY CarrierIdReplace ###.
Notice the names used by the query:
text
CarrierId
Name
CurrencyCodeThese are the CDS element names.
The consumer does not need to use:
text
carrier_id
currency_codewhen reading the CDS entity.
20. Compare direct-table and CDS queries
Direct table:
abap
SELECT FROM /dmo/carrier
FIELDS carrier_id,
name,
currency_code
ORDER BY carrier_idCDS entity:
abap
SELECT FROM zi_carrier_###
FIELDS CarrierId,
Name,
CurrencyCode
ORDER BY CarrierIdBoth ultimately read the same carrier data in this example.
But they represent different architectural dependencies:
text
Direct table query
Consumer
↓
Persistencetext
CDS query
Consumer
↓
CDS model
↓
Persistence21. Update the Reader to use CDS
Open:
text
ZCL_CARRIER_READER_###The Runner should not need to know that the Reader's source is changing.
We will keep the Reader's existing public result structure:
abap
TYPES:
BEGIN OF ty_carrier,
carrier_id TYPE /dmo/carrier-carrier_id,
name TYPE /dmo/carrier-name,
currency_code TYPE /dmo/carrier-currency_code,
END OF ty_carrier,
tt_carriers TYPE STANDARD TABLE OF ty_carrier
WITH EMPTY KEY.That means callers continue to receive components named:
text
carrier_id
name
currency_codeInside the Reader, however, the SQL source will become:
text
ZI_CARRIER_###22. Refactor GET_ALL
Lesson 1 version:
abap
METHOD get_all.
SELECT FROM /dmo/carrier
FIELDS carrier_id,
name,
currency_code
ORDER BY carrier_id
INTO TABLE @carriers.
ENDMETHOD.Change it to:
abap
METHOD get_all.
SELECT FROM zi_carrier_###
FIELDS CarrierId AS carrier_id,
Name AS name,
CurrencyCode AS currency_code
ORDER BY CarrierId
INTO TABLE @carriers.
ENDMETHOD.The Reader now consumes the CDS entity.
23. Why alias the ABAP SQL result?
The CDS entity exposes:
text
CarrierId
Name
CurrencyCodeThe Reader's existing public type contains:
text
carrier_id
name
currency_codeSo the ABAP SQL query maps the CDS element names back to the Reader's public result names:
abap
CarrierId AS carrier_idand:
abap
CurrencyCode AS currency_codeThis lets us change the Reader's data source without forcing the Runner to change its existing field names.
Encapsulation
The Reader's caller should depend on the Reader's contract.
The caller does not need to know every internal detail of how the Reader gets its data.
24. Refactor GET_BY_CURRENCY
Lesson 1 source:
abap
METHOD get_by_currency.
SELECT FROM /dmo/carrier
FIELDS carrier_id,
name,
currency_code
WHERE currency_code = @currency
ORDER BY carrier_id
INTO TABLE @carriers.
ENDMETHOD.CDS version:
abap
METHOD get_by_currency.
SELECT FROM zi_carrier_###
FIELDS CarrierId AS carrier_id,
Name AS name,
CurrencyCode AS currency_code
WHERE CurrencyCode = @currency
ORDER BY CarrierId
INTO TABLE @carriers.
ENDMETHOD.Notice that the WHERE condition uses the CDS element:
text
CurrencyCodenot the persistence field:
text
currency_code25. Refactor GET_BY_ID
Lesson 1 version:
abap
SELECT SINGLE FROM /dmo/carrier
FIELDS carrier_id,
name,
currency_code
WHERE carrier_id = @carrier_id
INTO @carrier.Change it to:
abap
SELECT SINGLE FROM zi_carrier_###
FIELDS CarrierId AS carrier_id,
Name AS name,
CurrencyCode AS currency_code
WHERE CarrierId = @carrier_id
INTO @carrier.The rest of the method remains:
abap
IF sy-subrc = 0.
found = abap_true.
ENDIF.26. Complete Reader implementation
After the refactor, the implementation should contain:
abap
CLASS zcl_carrier_reader_### IMPLEMENTATION.
METHOD get_all.
SELECT FROM zi_carrier_###
FIELDS CarrierId AS carrier_id,
Name AS name,
CurrencyCode AS currency_code
ORDER BY CarrierId
INTO TABLE @carriers.
ENDMETHOD.
METHOD get_by_currency.
SELECT FROM zi_carrier_###
FIELDS CarrierId AS carrier_id,
Name AS name,
CurrencyCode AS currency_code
WHERE CurrencyCode = @currency
ORDER BY CarrierId
INTO TABLE @carriers.
ENDMETHOD.
METHOD get_by_id.
CLEAR:
carrier,
found.
SELECT SINGLE FROM zi_carrier_###
FIELDS CarrierId AS carrier_id,
Name AS name,
CurrencyCode AS currency_code
WHERE CarrierId = @carrier_id
INTO @carrier.
IF sy-subrc = 0.
found = abap_true.
ENDIF.
ENDMETHOD.
ENDCLASS.Replace ###.
Activate the Reader.
27. Run the existing Runner
Open:
text
ZCL_SQL_L01_###Do not change its architecture just because the Reader's data source changed.
Run:
text
F9The Runner still calls:
text
Reader methodsThe Reader now reads:
text
ZI_CARRIER_###instead of:
text
/DMO/CARRIERThe complete path is:
text
Runner
↓
Reader
↓
ABAP SQL
↓
ZI_CARRIER_###
↓
/DMO/CARRIER28. What did we gain?
Before:
text
Reader
↓
database tableAfter:
text
Reader
↓
CDS data model
↓
database tableThe Reader now depends on a reusable model rather than directly on the persistence layout.
That CDS model can later grow to include:
text
expressions
relationships
semantic metadata
associations
authorization behavior
additional modeling layersConsumers can continue reading the CDS entity without duplicating that modeling logic in every class.
29. Data Preview vs SQL Console vs Reader
You now have three useful ways to inspect or consume the model.
Data Preview
text
CDS View Entity
↓
Data PreviewUseful for visually inspecting the CDS result.
SQL Console
text
CDS View Entity
↓
interactive ABAP SQL
↓
result gridUseful for experimenting with queries.
Reader
text
Application code
↓
Reader
↓
ABAP SQL
↓
CDS View EntityUseful for programmatic consumption inside your application code.
They all use the same CDS model for different development tasks.
30. Common mistakes
Creating define view instead of define view entity
Use:
abap
define view entityfor the course.
Selecting directly from /DMO/CARRIER after the refactor
After completing this lesson, the carrier Reader should consume:
text
ZI_CARRIER_###Using persistence names against the CDS entity
This is wrong when selecting from ZI_CARRIER_###:
abap
FIELDS carrier_idThe CDS entity exposes:
text
CarrierIdForgetting the source alias in CDS
If the source alias is:
text
Carrieruse:
abap
Carrier.carrier_idin the CDS element list.
Forgetting to activate
An inactive Data Definition is not the active version of the CDS model.
Activate with:
text
Ctrl + F3before consuming the latest version.
Confusing Data Definition and CDS View Entity
Remember:
text
Data Definition
= repository object containing CDS source
CDS View Entity
= data-model entity defined by that sourceTreating a CDS key as a new database constraint
The CDS key describes the entity's key semantics.
It does not create a new uniqueness constraint on /DMO/CARRIER.
31. Knowledge check
1. What does CDS stand for?
Show answer
Core Data Services.
2. What is a Data Definition?
Show answer
An ABAP repository object that contains CDS DDL source code and participates in repository functions such as syntax check, activation, and transport.
3. What does define view entity create conceptually?
Show answer
It defines a CDS View Entity: a reusable CDS data model over one or more data sources.
4. What is the data source here?
abap
as select from /dmo/carrier as CarrierShow answer
/DMO/CARRIER.
Carrier is the source alias.
5. What does this do?
abap
Carrier.carrier_id as CarrierIdShow answer
It exposes the source field carrier_id as the CDS element CarrierId.
6. Does the CDS entity store a second copy of /DMO/CARRIER data?
Show answer
No. The view entity models/selects data from its source. /DMO/CARRIER remains the persistence source.
7. Why did the Reader query use this alias?
abap
CarrierId AS carrier_idShow answer
The CDS entity exposes CarrierId, while the Reader's existing public result type exposes carrier_id. The ABAP SQL alias maps between those contracts so existing callers do not need to change.
8. What should the Runner know about /DMO/CARRIER after the refactor?
Show answer
Nothing directly. The Runner calls the Reader. The Reader owns its data-access implementation.
9. What shortcut activates the Data Definition?
Show answer
Ctrl + F3.
10. What shortcut opens CDS Data Preview from the data-definition editor?
Show answer
F8.
32. Lesson summary
You changed the application from:
text
Runner
↓
Reader
↓
ABAP SQL
↓
Database Tableto:
text
Runner
↓
Reader
↓
ABAP SQL
↓
CDS View Entity
↓
Database TableYou created:
text
ZI_CARRIER_###with:
abap
define view entity
as select from
key
asYou also used:
text
Data Definition creation
CDS code completion
syntax check
activation
CDS Data Preview
SQL Console
ABAP SQL consumption
Reader refactoringThe central architectural idea is:
CDS gives the application a reusable data-modeling layer between consumers and persistence.
33. What comes next?
Lesson 3 — CDS Expressions, Calculated Elements, and Filtering extends the model with data-processing capabilities such as:
text
calculated elements
literals
CASE
built-in expressions/functions
filtersLater lessons can introduce:
text
joins
associations
semantic annotationsThe same architecture will evolve without discarding the concepts from this lesson.