CDS - Migration of Views
Do you still have a lot of old Core Data Services in your ABAP system? Time to migrate to the new entity.
Table of contents
In this article, we will look at migration on-premise and in the cloud. We will use two examples to show you how to migrate your Core Data Services to the new views.
Introduction
The new views have been around for quite some time now, and with release 7.57 (S/4HANA 2022), the old Core Data Services are now obsolete. If you are on a current S/4 HANA release, you should start thinking about migrating the views. SAP provides various tools for this purpose, which we would like to take a closer look at in this article.
Migration (Report)
In this section, we will migrate our old Core Data Services using the reports provided. If you are not yet on S/4 HANA 2023, this is the preferred route. The migration reports will be available from S/4HANA 2021.
Preparation
Before we start the migration, the first step is to create an old Core Data Service in the system so that we can carry out the migration on it. To do this, we define a simple core data service based on the table BSEG (old financial positions).
@AbapCatalog.sqlViewName: 'ZBSIMIGPOS'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Migration Example (Position)'
@Metadata.ignorePropagatedAnnotations: true
define view ZBS_I_MigrationPosition
as select from bseg
{
key bukrs as CompanyCode,
key belnr as DocumentNumber,
key gjahr as FiscalYear,
key buzei as AccountingDocumentItem,
buzid as AccountingDocumentItemType,
augdt as ClearingDate,
augcp as ClearingCreationDate,
@Semantics.amount.currencyCode : 't001.waers'
dmbtr as AmountInCompanyCodeCurrency,
@Semantics.amount.currencyCode : 'bkpf.waers'
wrbtr as AmountInTransactionCurrency
}
On this view we define a consumption view that makes the data available externally as a sum.
@AbapCatalog.sqlViewName: 'ZBSCMIGPOS'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Migration Example (Consumption)'
define view ZBS_C_MigrationPosition
as select from ZBS_I_MigrationPosition
{
key CompanyCode,
key DocumentNumber,
key FiscalYear,
sum( AmountInCompanyCodeCurrency ) as SumForCompany,
sum( AmountInTransactionCurrency ) as SumForTransaction
}
group by
CompanyCode,
DocumentNumber,
FiscalYear
Analysis
In this phase we need the report RUTDDLS_MIGRATION_CANDIDATES to analyze the Core Data Services in the system that we want to migrate. If we run the report for the two views, we get an assessment of the migration possibility of the views.
In this case, we can migrate the two views and thus begin the implementation.
Implementation
For the implementation, we start with the report RUTDDLSV2MIGRATION and first start a simulation run for the two objects.
However, we now receive errors when implementing the objects. If we take a closer look at the protocol, we find the error message that the reference fields are not contained in the entity.
In the old views it was possible to refer to the reference field in the annotation and we did not have to specify this explicitly in the view. In this case we have to add the two fields to the Core Data Service via association. After adapting the basic view, it now looks like this.
@AbapCatalog.sqlViewName: 'ZBSIMIGPOS'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Migration Example (Position)'
@Metadata.ignorePropagatedAnnotations: true
define view ZBS_I_MigrationPosition
as select from bseg
association [1..1] to t001 as _Company on _Company.bukrs = $projection.CompanyCode
association [1..1] to bkpf as _Head on _Head.bukrs = $projection.CompanyCode
and _Head.belnr = $projection.DocumentNumber
and _Head.gjahr = $projection.FiscalYear
{
key bukrs as CompanyCode,
key belnr as DocumentNumber,
key gjahr as FiscalYear,
key buzei as AccountingDocumentItem,
buzid as AccountingDocumentItemType,
augdt as ClearingDate,
augcp as ClearingCreationDate,
@Semantics.amount.currencyCode : 'CompanyCurrency'
dmbtr as AmountInCompanyCodeCurrency,
_Company.waers as CompanyCurrency,
@Semantics.amount.currencyCode : 'DocumentCurrency'
wrbtr as AmountInTransactionCurrency,
_Head.waers as DocumentCurrency
}
We also need to adjust the Consumption View and include the fields from the view below.
@AbapCatalog.sqlViewName: 'ZBSCMIGPOS'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Migration Example (Consumption)'
define view ZBS_C_MigrationPosition
as select from ZBS_I_MigrationPosition
{
key CompanyCode,
key DocumentNumber,
key FiscalYear,
CompanyCurrency,
DocumentCurrency,
@Semantics.amount.currencyCode : 'CompanyCurrency'
sum( AmountInCompanyCodeCurrency ) as SumForCompany,
@Semantics.amount.currencyCode : 'DocumentCurrency'
sum( AmountInTransactionCurrency ) as SumForTransaction
}
group by
CompanyCode,
DocumentNumber,
FiscalYear,
CompanyCurrency,
DocumentCurrency
We can now start a second simulation run and check the result. So far, all tests have been successfully completed and we can initiate the implementation in the next step.
To do this, we set the report from "Simulation generation" to "Generate inactive version". This adjusts the two views, deletes the SQL views from the database and generates an inactive version. Since we are working in the $TMP package, we do not need to specify a transport for the implementation. Finally, we can now activate the two views. If we look at the base, only the head area has changed a little.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Migration Example (Position)'
@Metadata.ignorePropagatedAnnotations: true
define view entity ZBS_I_MigrationPosition
The number of annotations in the Consumption View has also decreased; annotations that are no longer needed are removed through the adjustment.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Migration Example (Consumption)'
define view entity ZBS_C_MigrationPosition
Migration (ADT Wizard)
In the next step, we use the wizard in the ABAP Development Tools to bring our data model from the Core Data Service training up to date. In the cloud (ABAP Environment, Public Cloud), this is the only way to migrate; on-premise, you can also use this route with an S/4HANA 2023 release.
Analysis
To start the analysis, we mark the Core Data Services that we want to have checked in the next step. The easiest way to do this is via the Project Explorer and by right-clicking in the context menu.
There you can see all the views that match the criteria. Entities that have already been converted are removed from the list. You can find the message in the top left area of the popup.
In the next step you can set the run, whether you want to carry out an analysis first or start directly with the migration.
The run will then take a corresponding amount of time depending on the number of objects.
As a result, we receive a popup with the corresponding run information. We can use the checkbox to display the faulty objects in order to analyze the errors. If you mark a view, you will see a comparison of the two resources (Current -> New) in the lower part and can view possible changes.
Adaptation
Since we still have views with errors, we must first correct all errors. In most cases, the messages indicate missing quantity and currency units. Here we again supplement the corresponding fields in the view with additional associations, by including the field in the view or by adding an annotation.
In a special case, we are informed about the data type in our Union example. Since we did not cast a specific type before, but created the Inline element by value (0), we now cast to a correspondingly suitable type.
define view ZBS_I_DmoUnion
as select from ZBS_C_DmoPositionError
{
key DocumentNumber,
key PositionNumber,
'Normal' as PositionType,
PositionPrice,
PositionCurrency
}
where
ErrorInConversion = ' '
union select from ZBS_C_DmoPositionError
{
key DocumentNumber,
key PositionNumber,
'Error' as PositionType,
cast( 0 as abap.curr(15,2) ) as PositionPrice,
PositionCurrency
}
where
ErrorInConversion = 'X'
You can find all the adjustments made in this commit in the GitHub repository so that you can understand the changes.
Migration
In the last step, we now make the changes to all views. To do this, we mark all views again and this time carry out the migration in real time to create inactive views in the system. In this case, the system also asks us for a transport. Using the "Assign" Button you can assign a transport to all objects and do not have to do this individually.
If you then mark all views, you can carry out a mass activation and the views should be able to be activated without any problems. Via the context menu; you will also find the option to activate it.
You can find the final views and the changes made through the migration via the commit in the GitHub repository.
Summary
Migrating the old views to the new entities definitely makes sense, since a second object, the SQL view, is no longer necessary. The activation times for views will also increase significantly, which will speed up our working time.
If you would like to know more in detail, you can find out more about the rules tested and the implementations made in the article linked below. There you can delve deeper into the topic of migration and requirements.
Hint: In some use cases, such as BW extraction or integration into customizing, the SQL views of Core Data Services are often used. You should therefore be careful when migrating "all" views.
Conclusion
In this article, we wanted to show you how easy it is to migrate Core Data Services and what tools are available to carry out the migration. With the right release, nothing should stand in your way, as there are more advantages than disadvantages.