Did you catch the Evolving data integration with SQL services and CDS external entities session at Devtoberfest 2025? If so, you’re already familiar with two key technologies that are modernizing data integration for ABAP systems: CDS External Entities, which allow you to seamlessly integrate external data into your ABAP CDS model, and SQL Services, which enable secure, external access to your ABAP-managed data.
The best part? When you combine these two, you can create a powerful ABAP-to-ABAP data federation that fits perfectly within the existing ABAP concepts. In this blog post, I’ll walk you through exactly how to apply these technologies.
If you’d like more background, I highly recommend checking out the Devtoberfest session recording and all related documentation:
Devtoberfest 2025: Recording / Slides Data Integration in ABAP Cloud: Documentation
But don’t worry – you’ll be able to follow this post even if you haven’t seen it. To demonstrate how CDS External Entities and SQL Services work together, I’ll use a simple scenario involving two ABAP systems: A Data Provider that exposes the data and a Data Consumer that accesses it. The entire scenario shown here was implemented on the SAP BTP ABAP Environment, Release 2508.
Content
Setting Up the Data Provider (System 1)
Our first system, the Data Provider, is responsible for making the data available. We’ll do this by exposing our entity through an SQL Service, making it accessible via standard SQL. The process is the same as if you were exposing it to a non-ABAP consumer.
Step 1: Define the Data Model with a CDS Table Entity
First, we need a data model. For this example, we’ll model our employee data using a simple CDS Table Entity.
@ClientHandling.type: #CLIENT_DEPENDENT
@AbapCatalog.deliveryClass: #APPLICATION_DATA
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Employee data’
define table entity ZEMPLOYEE_DATA
{
key id : abap.int4;
name : abap.string null;
@Semantics.amount.currencyCode: ‘salary_currency’
salary : abap.curr(15, 2);
salary_currency : abap.cuky;
primary_language : abap.lang;
}
Step 2: Create an Abstraction Layer with a CDS View Entity
Next, we’ll create a CDS View Entity on top of our table entity. This additional layer serves two purposes:
Abstraction: It provides a stable interface for our data model, allowing us to hide internal field names and implementation details from the consumer. Necessity: Currently, CDS Table Entities cannot be exposed directly in an SQL Service, so this view is required. It is planned to remove this artificial restriction in an upcoming release.@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Employee data view’
@Metadata.ignorePropagatedAnnotations: true
define view entity ZEMPLOYEE_DATA_V as select from ZEMPLOYEE_DATA
{
key id as Id,
name as Name,
@Semantics.amount.currencyCode: ‘SalaryCurrency’
salary as Salary,
salary_currency as SalaryCurrency,
primary_language as PrimaryLanguage
}
Step 3: Expose the View via an SQL Service
The final step on the provider side is to expose our view using an SQL Service. This is done with a Service Definition, where we also assign an alias (EmployeeData) for our entity. A corresponding SQL Service Binding is then created based on this definition.
@EndUserText.label: ‘Employee data service’
define service ZEMPLOYEE_DATA_SERVICE {
expose ZEMPLOYEE_DATA_V as EmployeeData;
}
Step 4: Define the Communication Scenario
To manage access, we need to define a Communication Scenario. This is where we bundle the necessary services and authorizations for our integration.
Since our goal is technical data integration between two systems (without applying business user authorizations), we’ll use the global SQL service for privileged access (Inbound Service S_PRIVILIGED_SQL1). Authorizations for accessing the specific CDS view are then managed through the S_SQL_VIEW authorization object.
Step 5: Administrator Configuration
Finally, an administrator completes the setup by configuring the Communication Scenario. This involves creating a Communication User, a Communication System and a Communication Arrangement.
With these steps, our Data Provider system is now fully configured and ready to serve data.
Setting Up the Data Consumer (System 2)
Now, let’s switch to our second system, the Data Consumer. Here, we want to access the data exposed by System 1. We’ll achieve this by integrating the data into our local CDS data model using a CDS External Entity.
Step 1: Define the CDS External Entity
The first step is to create a CDS External Entity that mirrors the structure of the data provided by our Data Provider. The external names must match the aliases we defined in the provider’s service definition and the abstraction view.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Remote employee data’
define external entity ZREMOTE_EMPLOYEE_DATA external name EmployeeData
{
key id : abap.int4 external name Id;
name : abap.string external name Name;
@Semantics.amount.currencyCode: ‘salary_currency’
salary : abap.curr(15, 2) external name Salary;
salary_currency : abap.cuky external name SalaryCurrency;
primary_language : abap.lang external name PrimaryLanguage;
}
with federated data provided by ZREMOTE_EMPLOYEE_SCHEMA
The with federated data provided by… clause points to a Logical External Schema. Think of this as a placeholder that we’ll link to a concrete remote connection in the next steps.
Step 2: Define the Outbound Communication Scenario
Just like on the provider side, we need a Communication Scenario to define the integration. This time, it’s an outbound service that represents our need to connect to an external endpoint, which provides our Logical External Schema.
Step 3: Configure the Communication Arrangement
To configure the scenario, an administrator creates a Communication System and a Communication Arrangement.
The Communication System points to our Data Provider (System 1). This is where you configure the remote SQL access with the endpoint details provided by the provider system. To authenticate, you’ll use the technical user that was configured back in System 1.
The Communication Arrangement is where the magic happens. It links the logical schema from our CDS External Entity (ZREMOTE_EMPLOYEE_SCHEMA) to the actual schema provided by the SQL Service Binding in System 1.
Once this is configured, you can go back to ADT and use the Data Preview on your CDS External Entity to test the connection and consume the data live from System 1! The static CDS External Entity integrates seamlessly into your local data model, allowing you to build on it and use it like a local entity. You could even place a new CDS View Entity on top and expose it again via an SQL Service, creating a powerful data federation chain.
A quick but important note: Type Mappings
As you may know, the ODBC Driver for ABAP and SQL Services can be used with different type mappings. You can find the full documentation on type mappings here. This is a crucial detail when using CDS External Entities.
When you consume an SQL Service via a CDS External Entity, you must ensure that the data types in your entity definitions match the type mapping used. You need to decide on a type mapping at design time already.
Let’s look at our example. If you configured the connection to use the semantic type mapping instead of the native one, you would see the following changes:
An abap.curr field would be exposed as abap.decfloat34 (with a decimal shift). An abap.lang field would be exposed as abap.char(2) (after language key conversion).
This means your CDS External Entity definition would need to be adjusted to match these new types:
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Remote employee data’
define external entity ZREMOTE_EMPLOYEE_DATA external name EmployeeData
{
key id : abap.int4 external name Id;
name : abap.string external name Name;
@Semantics.amount.currencyCode: ‘salary_currency’
salary : abap.decfloat34 external name Salary;
salary_currency : abap.cuky external name SalaryCurrency;
primary_language : abap.char(2) external name PrimaryLanguage;
}
with federated data provided by Z_REMOTE_EMPLOYEE_SCHEMA
For ABAP-to-ABAP data federation with CDS External Entities, the native type mapping is usually the right choice as it provides a direct, one-to-one mapping without conversions. A type mapping other than native, such as semantic type mapping, should only be used if the provider system needs to perform the conversions (for whatever reason).
Wrapping Up
This concludes our overview of ABAP-to-ABAP data integration using CDS External Entities and SQL Services. I hope this post demonstrates the power and elegance of this approach. For more, please explore our blog posts and repository with various examples on how to use SQL Services – also from non-ABAP.
I look forward to your questions and feedback in the comments below.
Did you catch the Evolving data integration with SQL services and CDS external entities session at Devtoberfest 2025? If so, you’re already familiar with two key technologies that are modernizing data integration for ABAP systems: CDS External Entities, which allow you to seamlessly integrate external data into your ABAP CDS model, and SQL Services, which enable secure, external access to your ABAP-managed data. The best part? When you combine these two, you can create a powerful ABAP-to-ABAP data federation that fits perfectly within the existing ABAP concepts. In this blog post, I’ll walk you through exactly how to apply these technologies. If you’d like more background, I highly recommend checking out the Devtoberfest session recording and all related documentation: Devtoberfest 2025: Recording / Slides Data Integration in ABAP Cloud: Documentation But don’t worry – you’ll be able to follow this post even if you haven’t seen it. To demonstrate how CDS External Entities and SQL Services work together, I’ll use a simple scenario involving two ABAP systems: A Data Provider that exposes the data and a Data Consumer that accesses it. The entire scenario shown here was implemented on the SAP BTP ABAP Environment, Release 2508.Content Setting Up the Data Provider (System 1) Our first system, the Data Provider, is responsible for making the data available. We’ll do this by exposing our entity through an SQL Service, making it accessible via standard SQL. The process is the same as if you were exposing it to a non-ABAP consumer. Step 1: Define the Data Model with a CDS Table EntityFirst, we need a data model. For this example, we’ll model our employee data using a simple CDS Table Entity. @ClientHandling.type: #CLIENT_DEPENDENT
@AbapCatalog.deliveryClass: #APPLICATION_DATA
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Employee data’
define table entity ZEMPLOYEE_DATA
{
key id : abap.int4;
name : abap.string null;
@Semantics.amount.currencyCode: ‘salary_currency’
salary : abap.curr(15, 2);
salary_currency : abap.cuky;
primary_language : abap.lang;
} Step 2: Create an Abstraction Layer with a CDS View Entity Next, we’ll create a CDS View Entity on top of our table entity. This additional layer serves two purposes: Abstraction: It provides a stable interface for our data model, allowing us to hide internal field names and implementation details from the consumer. Necessity: Currently, CDS Table Entities cannot be exposed directly in an SQL Service, so this view is required. It is planned to remove this artificial restriction in an upcoming release.@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Employee data view’
@Metadata.ignorePropagatedAnnotations: true
define view entity ZEMPLOYEE_DATA_V as select from ZEMPLOYEE_DATA
{
key id as Id,
name as Name,
@Semantics.amount.currencyCode: ‘SalaryCurrency’
salary as Salary,
salary_currency as SalaryCurrency,
primary_language as PrimaryLanguage
} Step 3: Expose the View via an SQL ServiceThe final step on the provider side is to expose our view using an SQL Service. This is done with a Service Definition, where we also assign an alias (EmployeeData) for our entity. A corresponding SQL Service Binding is then created based on this definition.@EndUserText.label: ‘Employee data service’
define service ZEMPLOYEE_DATA_SERVICE {
expose ZEMPLOYEE_DATA_V as EmployeeData;
} Step 4: Define the Communication ScenarioTo manage access, we need to define a Communication Scenario. This is where we bundle the necessary services and authorizations for our integration. Since our goal is technical data integration between two systems (without applying business user authorizations), we’ll use the global SQL service for privileged access (Inbound Service S_PRIVILIGED_SQL1). Authorizations for accessing the specific CDS view are then managed through the S_SQL_VIEW authorization object. Step 5: Administrator ConfigurationFinally, an administrator completes the setup by configuring the Communication Scenario. This involves creating a Communication User, a Communication System and a Communication Arrangement.With these steps, our Data Provider system is now fully configured and ready to serve data. Setting Up the Data Consumer (System 2) Now, let’s switch to our second system, the Data Consumer. Here, we want to access the data exposed by System 1. We’ll achieve this by integrating the data into our local CDS data model using a CDS External Entity. Step 1: Define the CDS External Entity The first step is to create a CDS External Entity that mirrors the structure of the data provided by our Data Provider. The external names must match the aliases we defined in the provider’s service definition and the abstraction view.@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Remote employee data’
define external entity ZREMOTE_EMPLOYEE_DATA external name EmployeeData
{
key id : abap.int4 external name Id;
name : abap.string external name Name;
@Semantics.amount.currencyCode: ‘salary_currency’
salary : abap.curr(15, 2) external name Salary;
salary_currency : abap.cuky external name SalaryCurrency;
primary_language : abap.lang external name PrimaryLanguage;
}
with federated data provided by ZREMOTE_EMPLOYEE_SCHEMA The with federated data provided by… clause points to a Logical External Schema. Think of this as a placeholder that we’ll link to a concrete remote connection in the next steps. Step 2: Define the Outbound Communication Scenario Just like on the provider side, we need a Communication Scenario to define the integration. This time, it’s an outbound service that represents our need to connect to an external endpoint, which provides our Logical External Schema. Step 3: Configure the Communication ArrangementTo configure the scenario, an administrator creates a Communication System and a Communication Arrangement. The Communication System points to our Data Provider (System 1). This is where you configure the remote SQL access with the endpoint details provided by the provider system. To authenticate, you’ll use the technical user that was configured back in System 1.The Communication Arrangement is where the magic happens. It links the logical schema from our CDS External Entity (ZREMOTE_EMPLOYEE_SCHEMA) to the actual schema provided by the SQL Service Binding in System 1.Once this is configured, you can go back to ADT and use the Data Preview on your CDS External Entity to test the connection and consume the data live from System 1! The static CDS External Entity integrates seamlessly into your local data model, allowing you to build on it and use it like a local entity. You could even place a new CDS View Entity on top and expose it again via an SQL Service, creating a powerful data federation chain. A quick but important note: Type MappingsAs you may know, the ODBC Driver for ABAP and SQL Services can be used with different type mappings. You can find the full documentation on type mappings here. This is a crucial detail when using CDS External Entities. When you consume an SQL Service via a CDS External Entity, you must ensure that the data types in your entity definitions match the type mapping used. You need to decide on a type mapping at design time already. Let’s look at our example. If you configured the connection to use the semantic type mapping instead of the native one, you would see the following changes: An abap.curr field would be exposed as abap.decfloat34 (with a decimal shift). An abap.lang field would be exposed as abap.char(2) (after language key conversion). This means your CDS External Entity definition would need to be adjusted to match these new types: @AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Remote employee data’
define external entity ZREMOTE_EMPLOYEE_DATA external name EmployeeData
{
key id : abap.int4 external name Id;
name : abap.string external name Name;
@Semantics.amount.currencyCode: ‘salary_currency’
salary : abap.decfloat34 external name Salary;
salary_currency : abap.cuky external name SalaryCurrency;
primary_language : abap.char(2) external name PrimaryLanguage;
}
with federated data provided by Z_REMOTE_EMPLOYEE_SCHEMA For ABAP-to-ABAP data federation with CDS External Entities, the native type mapping is usually the right choice as it provides a direct, one-to-one mapping without conversions. A type mapping other than native, such as semantic type mapping, should only be used if the provider system needs to perform the conversions (for whatever reason). Wrapping Up This concludes our overview of ABAP-to-ABAP data integration using CDS External Entities and SQL Services. I hope this post demonstrates the power and elegance of this approach. For more, please explore our blog posts and repository with various examples on how to use SQL Services – also from non-ABAP. I look forward to your questions and feedback in the comments below. Read More Technology Blog Posts by SAP articles
#SAP
#SAPTechnologyblog