Skip to content

Lesson 2 — Introduction to ABAP CDS ​

In Lesson 1, the application architecture was:

text
Runner
  ↓
Reader
  ↓
ABAP SQL
  ↓
Database Table

The 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 Table

You 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 ​

DurationAbout 90–120 minutes
EnvironmentSAP BTP ABAP Trial
Development toolEclipse with ABAP Development Tools (ADT)
PrerequisitesLesson 1, ABAP OOP, basic ABAP SQL
Persistence source/DMO/CARRIER
CDS entityZI_CARRIER_###
ReaderZCL_CARRIER_READER_###
RunnerZCL_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_ID

Replace ###

Use your own student/group suffix.

Example:

text
ZI_CARRIER_###  →  ZI_CARRIER_017

The 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/CARRIER

Imagine that several consumers need the same business-oriented representation of carrier data.

They may all need:

text
CarrierId
Name
CurrencyCode

rather than depending directly on persistence-oriented names:

text
carrier_id
name
currency_code

A reusable data model gives those consumers one shared definition.

text
Persistence
    ↓
Reusable CDS model
    ↓
Consumers

Main 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 annotations

Joins, 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 entity

Example:

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 entity

rather than the older:

abap
define view

4. 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-used

CDS 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 Entity

After 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/CARRIER

The persistence fields are:

text
carrier_id
name
currency_code

The CDS entity will expose:

text
CarrierId
Name
CurrencyCode

The 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_REQUIRED

states 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 Carrier

The data source is:

text
/DMO/CARRIER

The source alias is:

text
Carrier

That alias lets the element list clearly identify the source:

abap
Carrier.carrier_id
Carrier.name
Carrier.currency_code

Source 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 CarrierId

has:

text
Source field: carrier_id
CDS element:  CarrierId

Likewise:

abap
Carrier.currency_code as CurrencyCode

exposes:

text
currency_code → CurrencyCode

The 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 CarrierId

CarrierId 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:

  1. Expand your ABAP Cloud Project.
  2. Find your assigned package.
  3. 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 Object

Then select:

text
Core Data Services
  → Data Definition

Choose Next.


Step 12.3 — Enter the object details ​

Enter:

Name

text
ZI_CARRIER_###

Description

text
Lesson 2 - Carrier CDS

If your ADT wizard provides a Referenced Object field, enter:

text
/DMO/CARRIER

The 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:

  1. choose the request assigned for the course;
  2. 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 entity

Do not choose a template that generates the obsolete DDIC-based:

abap
define view

Choose 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 + Space

ADT 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 + F2

Check 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 alias

Fix the errors before activation.


16. Activate the Data Definition ​

Press:

text
Ctrl + F3

Activation creates the active CDS entity in the backend.

Checkpoint

At this point:

text
/DMO/CARRIER

still 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
F8

You can also use:

text
Open With
  → Data Preview

The preview should expose:

text
CarrierId
Name
CurrencyCode

Compare this with the persistence table:

text
/DMO/CARRIER

carrier_id
name
currency_code

The 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 CurrencyCode

so the element list becomes:

abap
{
  key Carrier.carrier_id as CarrierId,
      Carrier.name       as Name
}

Activate again:

text
Ctrl + F3

Open Data Preview again.

You should now see:

text
CarrierId
Name

The database table has not changed.

The CDS model has changed.

Restore:

abap
Carrier.currency_code as CurrencyCode

and 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 CarrierId

Replace ###.

Notice the names used by the query:

text
CarrierId
Name
CurrencyCode

These are the CDS element names.

The consumer does not need to use:

text
carrier_id
currency_code

when 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_id

CDS entity:

abap
SELECT FROM zi_carrier_###
  FIELDS CarrierId,
         Name,
         CurrencyCode
  ORDER BY CarrierId

Both ultimately read the same carrier data in this example.

But they represent different architectural dependencies:

text
Direct table query
Consumer
   ↓
Persistence
text
CDS query
Consumer
   ↓
CDS model
   ↓
Persistence

21. 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_code

Inside 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
CurrencyCode

The Reader's existing public type contains:

text
carrier_id
name
currency_code

So the ABAP SQL query maps the CDS element names back to the Reader's public result names:

abap
CarrierId AS carrier_id

and:

abap
CurrencyCode AS currency_code

This 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
CurrencyCode

not the persistence field:

text
currency_code

25. 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
F9

The Runner still calls:

text
Reader methods

The Reader now reads:

text
ZI_CARRIER_###

instead of:

text
/DMO/CARRIER

The complete path is:

text
Runner
  ↓
Reader
  ↓
ABAP SQL
  ↓
ZI_CARRIER_###
  ↓
/DMO/CARRIER

28. What did we gain? ​

Before:

text
Reader
  ↓
database table

After:

text
Reader
  ↓
CDS data model
  ↓
database table

The 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 layers

Consumers 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 Preview

Useful for visually inspecting the CDS result.

SQL Console ​

text
CDS View Entity
      ↓
interactive ABAP SQL
      ↓
result grid

Useful for experimenting with queries.

Reader ​

text
Application code
      ↓
Reader
      ↓
ABAP SQL
      ↓
CDS View Entity

Useful 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 entity

for 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_id

The CDS entity exposes:

text
CarrierId

Forgetting the source alias in CDS ​

If the source alias is:

text
Carrier

use:

abap
Carrier.carrier_id

in the CDS element list.


Forgetting to activate ​

An inactive Data Definition is not the active version of the CDS model.

Activate with:

text
Ctrl + F3

before 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 source

Treating 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 Carrier
Show answer

/DMO/CARRIER.

Carrier is the source alias.

5. What does this do? ​

abap
Carrier.carrier_id as CarrierId
Show 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_id
Show 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 Table

to:

text
Runner
  ↓
Reader
  ↓
ABAP SQL
  ↓
CDS View Entity
  ↓
Database Table

You created:

text
ZI_CARRIER_###

with:

abap
define view entity
as select from
key
as

You also used:

text
Data Definition creation
CDS code completion
syntax check
activation
CDS Data Preview
SQL Console
ABAP SQL consumption
Reader refactoring

The 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
filters

Later lessons can introduce:

text
joins
associations
semantic annotations

The same architecture will evolve without discarding the concepts from this lesson.