Core Data Services for ABAP

  • Fundamentals of CDS Data Modeling
    • Keying
    • Casting
    • Casing
    • Variables
    • Union
    • Join
    • Aggregation
    • Associations
    • Parameters
  • Authorization
  • How to 
    • Extension of standard CDS View
    • Dependency Analyzer
    • case shkzg
    • conversion
    • date functions
    • string functions
    • virtual elements
  • New
    • 7.54
      • CDS View Entity
      • ABAP CDS Projection view
    • 7.55
      • ABAP CDS Custom entity

Using CDS models, you can capture the data retrieval logic of your application in such a way that it can be executed directly in the database system.

In this design phase, the main aim is to identify and name the different data sources.
Before you start implementing your CDS models, you should take time to work out the fundamental data model of your application carefully and to clarify all open questions.

CDS view models are primarily based on SELECT statements, which are enriched with additional information.

Modeling Application Data

The core task of a business application is to read data, prepare it for display, present it to a user, receive new input or data changes by the user, check its consistency, process its impact, and finally persist the new data. It uses CDS views that prepare the raw data in a reusable way and add semantic metadata. The metadata is evaluated by infrastructure components, thus reducing the volume of individual programming.

Field labels 

Field names in CDS views should be understandable as well but are only expressed in one language usually English. Field labels, though, are supposed to be translated to many languages.
Additionally, it’s possible to define a field label by a field annotation in a CDS view: @EndUserText.label: '<field label>'.

In a CDS view, a field label can be determined by a data element or by an annotation.

Conversely, in a CDS view, only two label text variants can be defined by annotations:
  • The field label by @EndUserText.label
  • A short description called quick info by @EndUserText.quickInfo
Besides the labels, you can define further language-dependent texts in CDS views, such as a label for the CDS view itself, or some UI texts by UI annotations.

However, these texts can’t be derived from data elements—only from CDS view annotations.

Field Semantics: Quantities and Amounts

@Semantics.unitOfMeasure: true
OrderQuantityUnit,
@Semantics.quantity.unitOfMeasure: 'OrderQuantityUnit'
OrderQuantity,
@Semantics.amount.currencyCode: 'TransactionCurrency'
NetAmount,
@Semantics.currencyCode: true
TransactionCurrency,

Field Semantics: Aggregation Behavior

@DefaultAggregation: #SUM
OrderQuantity,
@DefaultAggregation: #SUM
NetAmount,
@DefaultAggregation: #NONE
NetPriceAmount,

Field Semantics: System Times

@Semantics.systemDate.createdAt: true
CreationDate,
@Semantics.systemTime.createdAt: true
CreationTime,
@Semantics.systemDate.lastChangedAt: true
LastChangeDate,
@Semantics.systemDateTime.lastChangedAt: true
LastChangeDateTime,

Field Semantics: Information for the Fiscal Year

@Semantics.fiscal.year: true
ryear as LedgerFiscalYear,
@Semantics.fiscal.period: true
poper as FiscalPeriod,
@Semantics.fiscal.yearVariant: true
periv as FiscalYearVariant,
@Semantics.fiscal.yearPeriod: true
fiscyearper as FiscalYearPeriod,

Foreign Key Relations

Foreign key relations can exist between CDS views as well.

define view I_ProfitCenter as selectdistinctfrom cepc
association[0..1] to I_Country as _Country
on $projection.Country = _Country.Country
{ …
@ObjectModel.foreignKey.association: '_Country'
land1 as Country,


@ObjectModel.representativeKey: 'Country'
define view I_Country as selectfrom t005
{ key cast(land1 as land1_gp preservingtype) as Country,
@ObjectModel.representativeKey: 'Region'
define view I_Region as selectfrom t005s
association [1..1] to I_Country as _Country
on $projection.Country = _Country.Country
{
@ObjectModel.foreignKey.association: '_Country'
key t005s.land1 as Country,
key t005s.bland as Region,
}

Text Relations

define view I_Bank as select from bnka
{ …
@ObjectModel.foreignKey.association: '_Country'
key banks as BankCountry,
@ObjectModel.text.element: [ 'BankName' ]
key bankl as BankInternalID,
@Semantics.text: true
banka as BankName,
}

define view I_Country as selectfrom t005
association [0..*] to I_CountryText as _Text
on $projection.Country = _Text.Country
{ @ObjectModel.text.association: '_Text'
key cast(land1 as land1_gp preservingtype) as Country,
}
@ObjectModel.dataCategory: #TEXT
@ObjectModel.representativeKey: 'Country'
define view I_CountryText as selectfrom t005t
{ key land1 as Country,
@Semantics.language: true
key spras as Language,
@Semantics.text: true
cast(landx50 as fis_landx50 preservingtype)
as CountryName,
}

Composition Relations

Composition relations are introduced that bring the related views into hierarchical parent-child relations.

Three types of composition associations are distinguished:
  •  #TO_COMPOSITION_PARENT The association points to the parent view.
  •  #TO_COMPOSITION_CHILD The association points to a child view.
  •  #TO_COMPOSITION_ROOT The association points to the root view of the object.
@ObjectModel.compositionRoot: true
define view I_SalesOrder …
association [0..*] to I_SalesOrderItem as _Item
on $projection.SalesOrder = _Item.SalesOrder
{ …
@ObjectModel.association.type: [#TO_COMPOSITION_CHILD]
_Item,
}

Time-Dependent Data

These date fields are annotated with @Semantics.businessDate.from: true and @Semantics.businessDate.to: true, respectively.

define view I_CostCenter as select …
{ key kokrs as ControllingArea,
key kostl as CostCenter,
@Semantics.businessDate.to: true
key datbi as ValidityEndDate,
@Semantics.businessDate.from: true
datab as ValidityStartDate,
}

Hierarchies

Leveled Hierarchies and Parent-Child Hierarchies
  • In leveled hierarchies, every hierarchy level has a separate data field.
Parent-Child Hierarchy

Virtual data model

The virtual data model (VDM) of SAP S/4HANA exposes the data together with its business semantics in an understandable and directly usable form. It consists of CDS views that are developed according to common standards and guidelines.
CDS technology is used to implement the VDM as a model of application data.

Names in VDM should be close to business reality, and names in the real world have no namespaces as well.  An entity (or “thing”) should be present in the model only once.

Identifier field: SalesOrder
Universally unique identifier (UUID): WBSElementInternalID
Code: CountryISOCode
Indicator: boolean Released or NotificationHasLongText
Amount and quantity field: OrderQuantity or MinDeliveryQtyInBaseUnit.
Points in time
Rates and Ratio 

* Always use your own namespace, for example, prefixes ZZ or YY, for your own custom field names when extending SAP standard views

An analytic query (abbreviated Qry), for example, C_GoodsMovementQuery
An analytic cube view, for example, I_SalesOrderItemCube
A view with language-dependent texts, for example, I_TaxCodeText
As value help (abbreviated VH), for example, C_CustomerMaterialValueHelp.
An overview page of an object in SAP Fiori, for example, C_InboundDeliveryObjPg

The name of a parameter of a VDM view consists of the prefix P and a semantical name

@ClientHandling.algorithm: #SESSION_VARIABLE
@EndUserText.label: 'Sales Order'
@VDM: {
viewType: #BASIC,
lifecycle.contract.type: #PUBLIC_LOCAL_API
}
@AccessControl: {
authorizationCheck: #CHECK,
personalData.blocking: #('TRANSACTIONAL_DATA'),
privilegedAssociations: [ '_CreatedByUser',
'_LastChangedByUser', '_BusinessAreaText',
'_CostCenterBusinessAreaText','_CreditControlAreaText' ]
}
@AbapCatalog: {
sqlViewName: 'ISDSALESORDER',
compiler.compareFilter: true
}
@ObjectModel: {
compositionRoot: true,
representativeKey: 'SalesOrder',
usageType: {
dataClass: #TRANSACTIONAL,
serviceQuality: #B,
sizeCategory: #L
}
}
@Metadata.ignorePropagatedAnnotations: true
@Analytics.dataCategory: #DIMENSION
define view I_SalesOrder
as selectfrom I_SalesDocument as SalesDocument

View Browser:SAP Fiori App for Browsing and Searching CDS Views

Modeling Analytical Applications (CUBE, like a Pivot table)

The main steps are the identification of measure and dimension fields, of cube and dimension views, and their connection by foreign key associations.

Analytic Cube: Transaction RSRTS_ODP_DIS
Analytic Queries

Modeling Transactional Applications

Transactional Object Models with BOPF 
A BOPF business object is generated from the CDS models in this described approach.

Native SAP HANA Functions in CDS

Using ABAP Managed Database Procedures (AMDP), it’s possible to execute SAP HANA SQLScript from ABAP while passing data via input parameters and receiving the results. This method is leveraged for CDS table functions.

Extensions of CDS Views

To be added 

Буфферизация

AbapCatalog.buffering.status – определяет, активна или нет буферизация, возможные значения:
#ACTIVE: Буферизация активна.
#SWITCHED_OFF: Буферизация возможна, но неактивна (по умолчанию).
#NOT_ALLOWED: Буферизация запрещена.

AbapCatalog.buffering.type – определяет тип буферизации, возможные значения:
#SINGLE: Отдельная запись
#GENERIC: Родовая область
#FULL: Полная буферизация
#NONE: Буферизация отключена (По умолчанию)

AbapCatalog.buffering.numberOfKeyFields – количество ключевых полей, относительно которых происходит буферизация, только для буферизации по родовой области (Generic). Может принимать значения от 0 до k-1, где k – количество ключевых полей.

Using annotations

CDS annotations enrich the plain SQL logic of CDS data models with additional metadata that is interpreted by the ABAP runtime environment and other consumers of the CDS models.

Access Controls

File  New  Data  ABAP  Core Data Services  Access Control.

@MappingRole: true
define role ZI_SalesOrder {
grant select on ZI_SalesOrder where 
  • ( SalesOrderType)= aspect pfcg_auth (V_VBAK_AAT, AUART, ACTVT = '03' ) and 
  • ( OrganizationDivision, SalesOrganization, DistributionChannel )= aspect pfcg_auth (V_VBAK_VKO,SPART,VKORG,VTWEG,ACTVT = '03' ); }
You can annotate your CDS models with @AccessControl.authorizationCheck… to specify whether an authorization check is required for a data selection.

Modeling the First CDS View

By default, the name you entered for the transport object—ZI_Product—is reused as the name of the CDS model. You can find it behind keywords to define a view.
  • Specify the name of the SQL view that is generated as representative of the CDS view in the database by the ABAP Data Dictionary (ABAP DDIC). The name must differ from the CDS view name. For this we can specify the name ZIFLIGHTS in the CDS data model by using the following annotation:
          @AbapCatalog.sqlViewName:'ZIFLIGHTS'

Fundamentals of CDS Data Modeling

Keying

CDS view fields are defined as key fields by adding the preceding syntax element key to the fields.
The key must be defined in such a way that it uniquely identifies a single record in the results list of a data selection. It’s recommended to keep the key as short as possible

The key definition serves as documentation of a CDS view model and can be used for consistency checks as well.

Casting 

You can use cast operations for determining the type of a calculated field and for converting the type of existing fields on the database level.

define view Z_ViewWithCasts
as selectdistinctfrom t000
{ t000.logsys as ProjectedField,
   '20170809' as CharacterField,
   cast ( '20170809' as abap.dats ) as DateField,
   cast ( cast ( 'E' as abap.lang ) as sylangu preservingtype) as LanguageField,

  1.2 as FloatingPointField,
  FLTP_TO_DEC(1.2 as abap.dec(4,2) ) as DecimalField }

Casing

Use case statements for defining conditional calculations in your CDS view logic.

define view Z_ViewWithCaseStatements
as select from ZI_SalesOrder
{

/* The first case statement checks the value of field SalesOrderType and sets the value of field IsStandardOrder to the constant X if the sales order type has a value of TAF or OAF. */

key SalesOrder,
case (SalesOrderType)
            when 'TAF' then 'X'
            when 'OAF' then 'X'
else ' ' end as IsStandardOrder,

cast( case (SalesOrderType)
when 'TAF' then 'X'
when 'OAF' then 'X'
else ' ' end as abap.char(3) ) as IsStandardOrderAsChar3,

case when SalesOrderType = 'TAF' then 'X'
when SalesOrderType = 'OAF' then 'X'
else ' ' end as IsStandardOrder2
}

In the following view, the column char1 of the database DEMO_EXPRESSIONS is cast to the data element demo_char_text with the same technical attributes. In this case, it is advisable to specify the addition PRESERVING TYPE.

@AbapCatalog.sqlViewName: 'DEMO_CDS_CAST_DE'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view demo_cds_cast_data_element
as select from
demo_expressions
{
cast ( char1 as DEMO_CHAR_TEXT preserving type) as char_with_text
};    

Variables 

CDS session variables allow you to access information regarding the current runtime session within the CDS view logic.

define view Z_ViewWithSessionVariables
as selectfrom t000
{
$session.client as ClientField,
$session.system_date as SystemDateField,
$session.system_language as SystemLanguageField,
$session.user as UserField
}
where mandt = $session.client

  • vname: Valued when accessed using ABAP SQL
  • user: Current user name, nominal value of the ABAP system field sy-uname
  • client: Current client. The default value is the nominal value of the ABAP system field sy-mandt. In reads with an ABAP SQL statement (with the addition USING CLIENT) and in calls of an AMDP method from ABAP (in whose declaration the addition AMDP OPTIONS CDS SESSION CLIENT is specified), the value specified here.
  • system_language: Text environment language of the current internal session, nominal value of the ABAP system field sy-langu
  • system_date: Current system date of the AS ABAP, nominal value of the ABAP system field sy-datum


Union

Union views combine and unify data records of different data sources.

define view Z_UnionViewWithoutAssociation
as selectfrom Z_ViewAsDataSourceA
{
key FieldA1 as UnionField1,
key FieldA2 as UnionField2,
key FieldA3 as UnionField3
}
union selectfrom Z_ViewAsDataSourceB
{
key FieldB2 as UnionField1,
key FieldB1 as UnionField2,
key '' as UnionField3
}

Join

Joins allow you to model conditional links between two data sources.

define view Z_ViewWithInnerJoin
as select from Z_ViewAsDataSourceD inner join Z_ViewAsDataSourceE
                  on Z_ViewAsDataSourceD.FieldD2 =Z_ViewAsDataSourceE.FieldE1
{
key Z_ViewAsDataSourceD.FieldD1,
key Z_ViewAsDataSourceD.FieldD2,
key Z_ViewAsDataSourceE.FieldE2
}

/*You should always specify the maximum target cardinality (TO ONE or TO MANY) of a left outer join partner. */

define view Z_ViewWithLeftOuterJoin
as select from Z_ViewAsDataSourceD
left outer to many join Z_ViewAsDataSourceE
...
/*When modeling your CDS view logic, you must consider this distinction and handle it if necessary. For example, when comparing field values in where conditions, you have to consider potential null values. */
where Z_ViewAsDataSourceE.FieldE2 is not null

Aggregation

SQL aggregation functions allow you to perform calculations of predefined aggregates efficiently on the database level.

define view Z_ViewWithAggregations
as selectfrom Z_ViewAggregationBase
{
key Field1,
min(Field3) as FieldWithMin,
max(Field3) as FieldWithMax,
avg(Field3) as FieldWithAvg,
cast( sum(Field3) as abap.int4 ) as FieldWithSum,
count( distinct Field1 ) as FieldWithCountDistinct,
count(*) as FieldWithCountAll
}
group by Field1

@AbapCatalog.sqlViewName: 'ZCDS_AGGR'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Aggregations'

define view Z_Cds_Agg_sum as select from snwd_stock 
    join snwd_pd on snwd_stock.product_guid = snwd_pd.node_key
    {    
    key snwd_pd.product_id,
    snwd_pd.category,    
    // Aggregate function "SUM"
    sum(snwd_stock.quantity) as total_stock    
    } 
    group by snwd_pd.category,
             snwd_pd.product_id

Points to be remembered
  • Every aggregate expressions used need an alternative element name defined using AS.
  • Aggregate expressions should require GROUP BY clause.
  • All non-aggregated fields used in CDS view should be specified in the GROUP BY clause.

Associations 

Associations can be used for modeling directed relationships between CDS Using associations
views.

Для упрощения понимания CDS View были введены так называемые ассоциации, которые по своей сути являются теми же JOIN, но в более простой для восприятия форме и с более широкими возможностями.

define view ZI_SalesOrder
...
/* The possible number of corresponding data records specifies the cardinality of an association. */
association [0..*] 
/*The name of an association can be specified by using the alias function AS. */
to ZI_SalesOrderItem as _Item
/* the association definition also comprises information about the correlation between the data records of the source and target view by means of an ON condition. */
on $projection.SalesOrder = _Item.SalesOrder
...

define view Z_ViewWithAssocWithDfltFilter
as select from ZI_Product 
association [0..*] to ZI_ProductText as _TextWithDefaultFilter
                       on $projection.Product = _TextWithDefaultFilter.Product
                        with default filter _TextWithDefaultFilter.Language = 'E'
association [0..*] to ZI_ProductText as _Text
                       on $projection.Product = _Text.Product
association [0..1] to ZI_ProductText as _TextInEnglish
                        on $projection.Product = _TextInEnglish.Product
                        and _TextInEnglish.Language = 'E'
{
Product,
_TextWithDefaultFilter.ProductName as ProductNameInEnglish,
_Text[1:Language='E'].ProductName as ProductNameInEnglish2,
_TextInEnglish.ProductName as ProductNameInEnglish3,
_TextWithDefaultFilter[Language='D'].ProductName
as ProductNameInGerman,
_TextWithDefaultFilter[*:left outer].ProductName as ProductName,
_TextWithDefaultFilter,
_Text,
_TextInEnglish
}

Parameters

Parameters affect the signature of the CDS models. Use parameters to do the following:
  • Define where conditions in a CDS view.
  • Calculate fields in the projection list of a CDS view.
  • Supply parameters of other data sources with the requested values.

define view Z_ViewWithParameters
with parameters
P_KeyDate : abap.dats,
P_Language : sylangu
...
where ValidityEndDate >=:P_KeyDate
and ValidityStartDate <=:P_KeyDate
and Language =:P_Language

Пример:

SQL запрос к CDS View с параметром:


define view Z_ViewWithParameters with parameters P_KeyDate : abap.dats, P_Language : sylangu as select from Z_ViewWithParametersDataSource association [0..*] to Z_ViewWithParametersAscTrgt as _Target on $projection.KeyField = _Target.KeyField association [0..1] to Z_ViewWithParametersAscTrgt as _FilteredTarget on $projection.KeyField = _FilteredTarget.KeyField and $projection.Language = _FilteredTarget.Language { key KeyField, ValidityEndDate, ValidityStartDate, :P_Language as Language, _Target(P_ValidityDate: :P_KeyDate)[1:Language= :P_Language].KeyField as TargetKeyField, _FilteredTarget } where ValidityEndDate >= :P_KeyDate and ValidityStartDate <= :P_KeyDate and Language = :P_Language


Conversion functions for the conversion of currencies and units of measure are based on several sets of persistent data records.

EXAMPLES 

Bill of material 

define view C_BillOfMaterial
as select from I_Billofmaterialwd as bomBO

//-- Association with BillOfMaterial Items
association [0..*] to C_BillOfMaterialItem as _BillOfMaterialItem on 
  • $projection.BillOfMaterial = _BillOfMaterialItem.BillOfMaterial and 
  • $projection.BillOfMaterialCategory = _BillOfMaterialItem.BillOfMaterialCategory and 
  • $projection.BillOfMaterialVariant = _BillOfMaterialItem.BillOfMaterialVariant and 
  • $projection.DraftUUID = _BillOfMaterialItem.ParentDraftUUID and 
  • $projection.BillOfMaterialVersion = _BillOfMaterialItem.BillOfMaterialVersion
association [0..1] to I_BillOfMaterialUsage as _BillOfMaterialVariantUsage on
  • $projection.BillOfMaterialVariantUsage = _BillOfMaterialVariantUsage.BillOfMaterialVariantUsage
  • and _BillOfMaterialVariantUsage.Language = $session.system_language
-- Technical associations
association [0..1] to C_BillOfMaterial as _SiblingEntity 
  •  on bomBO.BillOfMaterialHeaderUUID = _SiblingEntity.BillOfMaterialHeaderUUID
  • and bomBO.IsActiveEntity <> _SiblingEntity.IsActiveEntity
https://help.sap.com/viewer/8308e6d301d54584a33cd04a9861bc52/2020.000/en-US/5418de55938d1d22e10000000a44147b.html

CDS Views for Sales Master Data Management

Sales master data 

  • Sales Organization: I_SalesOrganization + I_SalesOrganizationText
  • Distribution Channel for Sales Org.: I_SlsOrganizationDistrChnl
  • Sales Offices for Sales Area: I_SalesAreaSalesOffice
  • Sales Groups for Sales office: I_SalesOfficeSalesGroup
  • Sales area: I_SalesArea
  • Incoterms Version: I_IncotermsVersion + I_IncotermsVersionText
  • Customer Material Information: I_CustomerMaterial
  • Material Statistics Group: I_MaterialStatisticsGroup + I_MaterialStatisticsGroupText
  • Item Category Group: I_ItemCategoryGroup + I_ItemCategoryGroupText
  • Partner Function: I_PartnerFunction + I_PartnerFunctionText

Pricing 

  • Condition type: I_PricingConditionType, I_ConditionType + I_ConditionTypeText

Sales Monitoring and Analytics

  • I_SalesContractItemCube (Analytics - Sales Contract Cube
  • I_SalesQuotationItemCube (Analytics - Sales Quotation Cube)
  • C_SalesOrderItemQry (Analytics - Incoming Sales Orders)
  • C_SalesVolumeAnalyticsQry (Analytics - Sales Volume)
  • C_RevenueFromInvoiceQry (Analytics - Sales Volume Flexible Analysis)
  • I_SalesAnalyticsCube_1 (Analytics - Sales Volume and Open Sales Cube)
  • C_SalesAnalyticsQry_1 (Analytics - Sales Volume and Open Sales)
  • I_SlsOrdConfAnalyticsCube (Analytics - Confirmation of Sales Orders Cube)
  • C_SlsOrdConfAnlytsQry (Analytics - Confirmation of Sales Orders)
  • I_DeliveryDocumentItemCube (Analytics - Delivery Cube)
  • I_CustomerReturnItemCube (Analytics - Customer Return Cube)
  • C_CustomerReturnItemQry (Analytics - Customer Return)
  • I_CreditMemoRequestItemCube (Analytics - Credit Memo Request Cube)
  • I_DebitMemoRequestItemCube (Analytics - Debit Memo Request Cube)

Sales order management and processing

  • I_SDDocumentProcessFlow
  • I_SDDocumentMultiLevelProcFlow
  • I_SalesOrder
  • I_SalesOrderPartner
  • I_SalesOrderPricingElement
  • I_SalesOrderItem
  • I_SalesOrderItemPartner
  • I_SalesOrderItemPricingElement
  • I_SalesQuotation
  • I_SalesQuotationPartner
  • I_SalesQuotationPrcgElmnt
  • I_SalesQuotationItem
  • I_SalesQuotationItemPartner
  • I_SalesQuotationItemPrcgElmnt
  • I_SalesDocumentScheduleLine

To retrieve the incoterms version of a customer

  • I_IncotermsVersion (Incoterms Version) and I_IncotermsVersionText (Incoterms Version Text)

To retrieve the statistics group of a material

  • I_MaterialStatisticsGroup (Material Statistics Group) and I_MaterialStatisticsGroupText (Material Statistics Group Text)

Contract data

  • Sales Scheduling Agreement (I_SalesSchedgAgrmt)
  • Sales Scheduling Agreement Item (I_SalesSchedgAgrmtItem)
  • Delivery Schedule of Sales Scheduling Agreement (I_SalesSchedgAgrmtDelivSched)
  • Schedule Line of Sales Scheduling Agreement (I_SalesSchedgAgrmtSchedLine)
  • Shedule Line History of Sales Scheduling Agreement (I_SalesSchedgAgrmtSchdLnHist)
  • I_SalesContractItem

Billing

  • I_BillingDocumentBasic (Billing Document Basic)
  • I_BillingDocumentItemBasic (Billing Document Item Basic)
  • I_BillingDocumentPartnerBasic (Billing Document Partner Basic)
  • I_BillingDocItemPartnerBasic (Billing Document Item Partner Basic)
  • I_BillingDocumentPrcgElmntBasic (Billing Document Pricing Element Basic)
  • I_BillingDocItemPrcgElmntBasic (Billing Document Item Pricing Element Basic)
  • I_BillingDocument (Billing Document)
  • I_BillingDocumentItem (Billing Document Item)
  • I_BillingDocumentPartner (Billing Document Partner)
  • I_BillingDocumentItemPartner (Billing Document Item Partner)
  • I_BillingDocumentPrcgElmnt (Billing Document Pricing Element)
  • I_BillingDocItemPrcgElmnt (Billing Document Item Pricing Element)

How to

How to use String Functions in ABAP CDS Views

CONCAT(arg1, arg2)

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {

    // CONCATENATE name1 & name2 
    CONCAT( kna1.name1, kna1.name2 ) as full_name
}

CONCAT_WITH_SPACE(arg1, arg2, spaces)

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {

    // CONCATENATE name1 & name2 with 4 space
    CONCAT_WITH_SPACE( kna1.name1, kna1.name2, 4 ) as full_name
}

SUBSTRING(arg, pos, len)

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {
    
    // To get substring for a given string
    SUBSTRING( kna1.name1, 2, 10) as name
}

LENGTH(arg)

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {
    
    // To get length for a given string
    LENGTH( kna1.name1 ) as name_length
}

LEFT(arg, len) & RIGHT(arg, len)

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {
    
    // To get length for a given string     
    LEFT( kna1.name1, 3) as name_left,
    RIGHT( kna1.name1, 3) as name_right,
    kna1.name1
}

LTRIM(arg, char) & RTRIM(arg, char)

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {
    
    // Removes the trailing blanks and character 
    LTRIM( kna1.name1, 'L') as name_lt,
    RTRIM( kna1.name1, 'T') as name_rt    
}

Case shkzg

 case shkzg
    when 'S'
    then matdoc.menge
    else matdoc.menge * -1
  end        as Quantity,


How to 

Authorization

We all know how authorization works in ABAP, most of the authorization checks are implemented in ABAP using ABAP statement AUTHORITY-CHECK which depends upon the PFCG role assigned to the user.

So, to provide authorization checks in ABAP CDS view a new repository object called Data Control Language (“DCL”) introduced.

DCL definition is created in DCL editor in eclipse ABAP Development Tool(ADT) using the keyword DEFINE ROLE …

Create role 


@EndUserText.label: 'Demo: Authorization Check' 
@MappingRole: true 
define role Zflight_Role_A 
   { 
    grant 
        select 
            on Zflight_ACCESS_CONTROL_A  // CDS VIEW 
            where carrid<> 'AZ';            
}

Assign to the CDS View 


@AbapCatalog.sqlViewName: 'ZAC_A'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Access Control B'
define view Zflight_ACCESS_CONTROL_A
as select from spfli
{
*
}

Now that we applied authorization check using DCL: the data preview of CDS view retrieves all data records except CARRID <> ‘AZ’. The database interface will automatically filter the selection results according to the access condition.

Annotations in DCL
@EndUserText.label:
The translatable short text for role
@MappingRole:
Value true: Role is implicitly to all users

Annotations in DDL
@AccessControl.authorizationCheck:
#CHECK: Perform authorization check, Syntax warming if no role is assigned
#NOT_REQUIRED: Similar to #CHECK but suppress syntax warning
#NOT_ALLOWED: No authorization check. Syntax warning if role is assigned.

Extend standard CDS View

A CDS view is extended by creating a new DDL source with DDL statement EXTEND VIEW.

As we know for every DDL source we have 2 corresponding dictionary objects created:
  • The CDS View and
  • SQL View
So when you extend a CDS view, there will be two corresponding objects created:
  • The CDS view extension and
  • Append View
  • New – Other ABAP Repository Object – Core Data Services – Data Definition to open the creation wizard;
  • Select the Extend View template and choose Finish.
  • In DDL source code editor, enter the necessary information for names of the append view
  • Save and activate the newly created CDS view extension.
  • After successful activation, check the DDL SQL Append View “Z” in SE11 transaction.
Notes:
  • A standard CDS view can be extended using multiple CDS view extensions.
  • The annotation AbapCatalog.viewEnahancementCategory must be specified in ABAP CDS view with any of these values #PROJECTION_LIST, #GROUP_BY and #UNION.
  • A CDS view with AbapCatalog.viewEnahancementCategory as #NONE cannot be extended.

Dependency Analyzer

The Dependency Analyzer view for CDS view provides you the information about the database tables and other CDS views used in a particular view. To see the Dependency Analyzer for CDS View right click on CDS View and select Open With and Dependency Analyzer.


ABAP CDS

ASSOCIATION TO PARENT, SELECT

Defines a CDS to-parent association (or to-parent association for short) with the name _assoc in a SELECT statement of a CDS view. A to-parent association associates the current CDS entity, as a source data source, with the target data source target specified in the definition of the to-parent association. To-parent associations are specialized CDS associations and are defined in CDS entities using the keyword ASSOCIATION TO PARENT.

ASSOCIATION, SELECT

... ASSOCIATION [ [min..max] ] TO target [AS _assoc] ON cond_exp
                [ WITH DEFAULT FILTER cond_exp ] ...

Addition 1 

... [min..max] 
 
Defines the cardinality of the target data source of a CDS view, which is defined with a CDS association ASSOCIATION. The square brackets [ ] are part of the syntax. For min and max, positive integers (including 0) and asterisks (*) can be specified: 
◾max cannot be 0.
◾An asterisk * for max means any number of rows.
◾min can be omitted (set to 0 if omitted).
◾min cannot be *.
◾When a CDS association is used in a WHERE condition, 1 must be specified for max.

If the cardinality is not defined explicitly, the cardinality "to 1" is used implicitly ([min..1]). 

A cardinality is specified to document the semantics of the data model and, in some database systems, for optimizations. In these database systems, LEFT OUTER JOINs produced by a path expressions are given the addition TO ONE if an explicit or implicit "to 1" cardinality is used and the addition TO MANY if any other cardinality is used. These additions work in the same way as when they are specified explicitly in LEFT OUTER JOIN. This means that an optimization is attempted and the result can be undefined if the results set does not match the cardinality. 

 Notes 
◾To avoid undefined and platform-dependent behavior, the cardinality should always be defined to match the data in question.
◾The specified cardinality is evaluated by the syntax check for paths specified in the CDS DDL of CDS or in ABAP SQL. A non-matching cardinality usually produces a syntax check warning.

 Example 

Specifies the cardinality of a CDS association incorrectly. The following CDS view joins the database tables SCARR and SPFLI in af CDS association _spfli without specifying the cardinality explicitly. The implicitly set cardinality is "to 1". If the CDS association is used in a path specified in the SELECT list, this is characterized in some database systems (for example the SAP HANA database) as a left outer join using the implicit addition TO ONE. The actual cardinality of the data is, however, TO MANY. 
@AbapCatalog.sqlViewName: 'DEMOCDSWRGC' 
define view demo_cds_wrong_cardinality 
  as select from 
    scarr 
    association to spfli as _spfli on 
      _spfli.carrid = scarr.carrid 
    { 
      scarr.carrid   as carrid, 
      scarr.carrname as carrname, 
      _spfli.connid  as connid 
    } 
The program DEMO_CDS_WRONG_CARDINALITY uses different SELECT statements to access the view. On optimizing database systems, such as the SAP HANA database, the two reads return a different number of rows, potentially an unexpected result. 

 Example 

Specifies the cardinality of a CDS association correctly. The following CDS view joins the database tables SCARR and SPFLI in a CDS association _spfli while specifying the cardinality explicitly. If the CDS association is used in a path specified in the SELECT list, this is characterized in some database systems (for example the SAP HANA database) as a left outer join using the implicit addition TO MANY, which matches the actual cardinality of the data.@@DDL@@DEMO_CDS_EXPLICIT_CARDINALITY@@ 

The program DEMO_CDS_EXPLICIT_CARDINALITY uses different SELECT statements to access the view. The two reads return the same number of rows on all database systems. 


 
 Addition 2 

... AS _assoc 
 
Defines the name _assoc of a CDS association of a CDS view defined using ASSOCIATION. If no name is defined explicitly using AS, _assoc is set implicitly to the name of the target data source. The name _assoc must comply with the naming rules for names. 

 Note : It is advisable to use an underscore _ as the first character of the CTE CDS association name. 

 Example 

Example of a simple CDS association. The following CDS view provides the same result as the CDS view DEMO_CDS_SCARR_SPFLI in the joins example, as shown in the program DEMO_CDS_ASSOCIATION using an assertion. Furthermore, the CDS association spfli_scarr is published to be used from outside in the SELECT list by specifying a path that contains only the name of a CDS association. The program DEMO_CDS_ASSOCIATION also shows how the CDS association can be accessed by specifying a path in ABAP SQL.
@AbapCatalog.sqlViewName: 'DEMO_CDS_ASSOC' 
@AccessControl.authorizationCheck: #NOT_REQUIRED 
define view demo_cds_association( 
 _spfli_scarr, 
 id, 
 carrier, 
 flight, 
 departure, 
 destination 
 ) 
 as select from 
 spfli 
 association [1..1] to scarr as _spfli_scarr on 
 $projection.carrid = _spfli_scarr.carrid 
 { 
 _spfli_scarr, 
 key spfli.carrid, 
 key _spfli_scarr[inner].carrname, 
 key spfli.connid, 
 spfli.cityfrom, 
 spfli.cityto 
 }     
 Example 

The following CDS view sales_order_invoice_header returns information about sales invoices and works with the database tables snwd_so_inv_head, snwd_so, snwd_bpa, and snwd_so_inv_item. 

Two CDS associations are defined: 
◾_buyer stands for a join between the current view and the target data source snwd_bpa.
◾_invoice_items stands for a join between the current view and the target data source snwd_so_inv_item.

The source data source fields used in the ON conditions - node_key and buyer_guid - are part of the SELECT list. Here the prefix $projection is used instead of the prefixes snwd_so_inv_head or snwd_so_inv_head. 

The CDS association _buyer is not listed in the SELECT list and can only be used in path expressions of the current SELECT statement. This association can be specified in the WHERE condition due to the cardinality [1..1]. The CDS association _invoice_items is not accessed in path expressions of the current SELECT statement. However, this association is listed in the SELECT list, which means it can be used in path expressions of other CDS views. This association cannot be specified in a WHERE condition due to the cardinality [1..*]. 
@AbapCatalog.sqlViewName: 'SALESO_INVHDR_VW' 
define view sales_order_invoice_header as 
  select from snwd_so_inv_head 
           inner join snwd_so 
             on snwd_so_inv_head.so_guid = snwd_so.node_key 
         association [1..1] to snwd_bpa as _buyer 
           on $projection.buyer_guid = _buyer.node_key 
         association [1..*] to snwd_so_inv_item as _invoice_items 
           on $projection.node_key = _invoice_items.parent_key 
         { key snwd_so_inv_head.node_key,      //used in assoc _invoice_items 
               snwd_so_inv_head.buyer_guid,    //used in assoc _buyer 
               snwd_so.so_id as sales_order_id, 
               _buyer.bp_id as buyer_id,       //from assoc _buyer 
               snwd_so_inv_head.payment_status, 
              @Semantics.currencyCode 
               snwd_so_inv_head.currency_code, 
              @Semantics.amount.currencyCode: 'currency_code' 
               snwd_so_inv_head.gross_amount, 
               _invoice_items                  //publish assoc _invoice_items 
         } 
          where _buyer.bp_role = '001';          //usage of assoc buyer 
 
The CDS view can be accessed in an ABAP program with a simple ABAP SQL SELECT statement. 
SELECT sales_order_id, buyer_id, payment_status 
       FROM sales_order_invoice_header 
       INTO CORRESPONDING FIELDS OF TABLE @itab. 
The complexity of the actual query is wrapped transparently in the CDS view for the application programmer. When the view is accessed, the join (defined by the CDS association _invoice_items) between snwd_so_inv_head and snwd_so_inv_item is not built, because there are no path expressions that need to access the join. 

The CDS view sales_order_invoice_header mentioned above is used as the the data source in the definition of the CDS view sales_order_invoice_items. This data source is used to access the published CDS association _invoice_items. The elements of the CDS association are accessed in this view. There is no visual indication that it is the result of a join. This join between snwd_so_inv_head and snwd_so_inv_item is created when the CDS view sales_order_invoice_items is activated. The other CDS association _buyer of the CDS view sales_order_invoice_header cannot be accessed. 
@AbapCatalog.sqlViewName: 'SALESO_INVITM_VW' 
define view sales_order_invoice_items as 
  select from sales_order_invoice_header as header 
  { header.sales_order_id, 
    header._invoice_items.inv_item_pos as item_position, 
   @Semantics.currencyCode 
    header._invoice_items.currency_code, 
   @Semantics.amount.currencyCode: 'currency_code' 
    header._invoice_items.gross_amount } 

 
 Addition 3 

... WITH DEFAULT FILTER cond_exp 
 
Defines a standard filter condition for a path expression. 
◾If a filter condition is specified when the CDS association is used in a path expression in the attributes attributes, this condition is used instead of the default filter condition.

Note: When the syntax check evaluates a cardinality specified using [min..max], the default filter condition is respected alongside the ON condition. 

Conversion

Unit
@AbapCatalog.sqlViewName: 'zcds_unit_sql'
define view zcds_unit as select from sbook
{
  bookid,
  unit_conversion (
    quantity =&gt; luggweight,
    source_unit =&gt; wunit,
    target_unit =&gt; cast( 'G' as abap.unit ) ) as `Weight_In_Grams
}


Currency
@AbapCatalog.sqlViewName: 'zcds_curr _sql'
@ClientDependent: true
define view zcds_curr as select from sbook
{
 currency_conversion(
    amount =&gt; loccuram,
    source_currency =&gt; loccurkey,
    target_currency =&gt; cast('EUR' as abap.cuky(5)),
    exchange_rate_date =&gt; order_date ) as euro_amount
}

Date functions

The date function DATE_IS_VALID is used to validate the date contains the valid SAP date format “YYYYMMDD“.

It returns “1” if the date is in valid date format else “0“. If the date is blank it returns “0“.



@AbapCatalog.sqlViewName: 'ZCDS_DATE'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Date Functions'
define view zcds_date_functions
            with parameters p_from_date:abap.dats
            as select from snwd_so
 {
  snwd_so.buyer_guid,
  snwd_so.billing_status,
  
  // returns 1 - Valid Date
  // returns 0 - Invalid Date
  DATS_IS_VALID(:p_from_date) as from_date
}


This function DATS_DAYS_BETWEEN calculates the no of days between the two specified dates, date1 and date2.

@AbapCatalog.sqlViewName: 'ZCDS_DATE'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Date Functions'
define view zcds_date_functions
            as select from vbak
 {
  vbak.vbeln,  //Sales Document
  vbak.auart,  //Sales Document Type
  vbak.audat,  //Document Date
  vbak.vdatu,  //Requested delivery date
  
  DATS_DAYS_BETWEEN(audat, vdatu) as no_of_days
}

DATS_ADD_DAYS adds days to the specified date date.
@AbapCatalog.sqlViewName: 'ZCDS_DATE'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Date Functions'
define view zcds_date_functions
            as select from vbak
 {
  vbak.vbeln,  //Sales Document
  vbak.auart,  //Sales Document Type
  vbak.audat,  //Document Date
  vbak.vdatu,  //Requested delivery date
  
  DATS_ADD_DAYS(vdatu, 10, 'NULL')     as option2,  //add 10 days
  DATS_ADD_DAYS(vdatu, -10, 'NULL')    as option1,  //substract 10 days
  DATS_ADD_DAYS(vdatu, 5, 'FAIL')      as option3,
  DATS_ADD_DAYS(vdatu, 4, 'INITIAL')   as option4,
  DATS_ADD_DAYS(vdatu, 2, 'UNCHANGED') as option5
}


The date function DATS_ADD_MONTHS add months to the specified date.
@AbapCatalog.sqlViewName: 'ZCDS_DATE'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Date Functions'
define view zcds_date_functions 
            as select from vbak
 {
  vbak.vbeln,  //Sales Document
  vbak.auart,  //Sales Document Type
  vbak.audat,  //Document Date
  vbak.vdatu,  //Requested delivery date
  
  DATS_ADD_MONTHS(vdatu, 10, 'NULL')     as option1,  //add 10 months
  DATS_ADD_MONTHS(vdatu, -10, 'NULL')    as option2,  //substract 10 months 
  DATS_ADD_MONTHS(vdatu, 5, 'FAIL')      as option3, 
  DATS_ADD_MONTHS(vdatu, 4, 'INITIAL')   as option4,
  DATS_ADD_MONTHS(vdatu, 2, 'UNCHANGED') as option5
}

String functions 

CONCAT(arg1, agr2) string function can be used to concatenate two character strings.

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {

    // CONCATENATE name1 & name2 
    CONCAT( kna1.name1, kna1.name2 ) as full_name
}

This string function is used to concatenate two character strings with space. The number of blanks between the arguments arg1 and arg2 is specified in spaces.

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {

    // CONCATENATE name1 & name2 with 4 space
    CONCAT_WITH_SPACE( kna1.name1, kna1.name2, 4 ) as full_name
}

 
To get sub string of arg from the position pos in the lenght len.
@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {
    
    // To get substring for a given string
    SUBSTRING( kna1.name1, 2, 10) as name
}

It returns the no of characters in the string which is passed as a argument arg. It ignores trailing blanks.

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {
    
    // To get length for a given string
    LENGTH( kna1.name1 ) as name_length
}

LEFT(arg, len) – It returns the left-side part of the string which is passed as argument arg of length len.

RIGHT(arg, len) – It returns the right-side part of the string which is passed as argument arg of length len.

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {
    
    // To get length for a given string     
    LEFT( kna1.name1, 3) as name_left,
    RIGHT( kna1.name1, 3) as name_right,
    kna1.name1
}

LTRIM(arg, char) – It removes the trailing blanks and leading character which matches the parameter char.

RTRIM(arg, char) – It removes the trailing blanks and trailing character which matches the parameter char.

@AbapCatalog.sqlViewName: 'ZCDS_STR_FUN'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'String Functions'
define view Zcds_Sql_Func as select from kna1 {
    
    // Removes the trailing blanks and character 
    LTRIM( kna1.name1, 'L') as name_lt,
    RTRIM( kna1.name1, 'T') as name_rt    
}

Virtual elements

For instance, a business requirement need us to add a field to the CDS view which is calculated using ABAP code. To achieve such kind of requirements we can use virtual elements.

You can use virtual elements to implement following use cases:
  • To define calculated field values that are not part of database tables
  • Filtering of calculated field values
  • Sorting of calculated field values.
There are two steps in implementing a virtual element in CDS view. They are
  • Adding Annotations
  • Implementing ABAP Code Exists
@ObjectModel.readOnly: true
@ObjectModel.virtualElement: true
@ObjectModel.virtualElementCalculatedBy: ‘ABAP:<code_exit_class>’

Create an ABAP code exit class and add the interface IF_SADL_EXIT_CALC_ELEMENT_READ.

Implement interface methods GET_CALCULATION_INFO and CALCULATE in custom code exit class to write the ABAP source code logic.

@AbapCatalog.sqlViewName: 'ZCDSVIRELE'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Demo Virtual Elements'
 
@OData.publish: true
 
define view ZSL_CDSVIRTUALELEM
  as select from snwd_pd
{
 
  key node_key   as ProductGuid,
      product_id as ProductId,
      type_code  as CategoryCode,
      category,
      supplier_guid as SupplierGuid,
      tax_tarif_code as TaxTarifCode,
      price as Price,
      
      @ObjectModel.readOnly: true
      @ObjectModel.virtualElement: true
      @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_DEMO_CODE_EXIT'
      cast( '' as abap.char(4)) as Discount 
}

Secondly, create a new ABAP class in SE24 and add the interface IF_SADL_EXIT_CALC_ELEMENT_READ.

  • GET_CALCULATION_INFO
    • Provides a list of all elements that are required for calculating the values of the virtual elements
  • CALCULATE
    • Executes the field calculation



New

CDS View Entity (7.54)

ABAP Core Data Services (CDS) is the implementation of the general CDS for ABAP. It defines semantic data models on standard tables and optimized them for the SAP HANA database. With ABAP release 7.55 (or) S/4HANA 2020, ABAP CDS view entity, a new type of CDS view. ABAP CDS view entities will replace the DDIC-based CDS views.

A CDS DDIC-based view is defined using the statement DEFINE VIEW.

The CDS View Entity a new kind of CDS view. A CDS view entity is defined with the statement DEFINE VIEW ENTITY. Similar to the CDS DDIC-based views, CDS view entities are used to model data sources based on database tables or other CDS entities.

@AccessControl.authorizationCheck: #NOT_ALLOWED 
DEFINE VIEW ENTITY demo_cds_view_entity 
 AS SELECT FROM scustom
 
    JOIN sbook 
    ON scustom.id = sbook.customid
     {
           scustom.id,
           scustom.name,
           sbook.bookid
     }
As the CDS view entity are new and more features will be added in future. Following are the restrictions at the time of writing this blog.
  • Select all elements from the data source using SELECT * is not supported in CDS view entities.
  • DISTINCT keyword and UNION clause is not yet supported.
  • It is not allowed to define a client field in the SELECT list.
It is recommended to use CDS view entities instead of CDS DDIC-based view due to technical improvements.

ABAP CDS Projection view (7.54)

There are currently three types of CDS views available: 
  • CDS DDIC-based views (DEFINE VIEW), 
  • CDS Projection views (DEFINE VIEW ENTITY AS PROJECTION) and 
  • CDS View Entities (DEFINE VIEW ENTITY) –  > ABAP 7.55 (or) S/4HANA 2020
The underlying CDS entity used in the projection view is called a projected entity. The projected entity can be a CDS view without parameters. 

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Projection View for BuPa'
define view entity DEMO_SALES_PV_BUPA  
  as projection on DEMO_SALES_CDS_BUPA
{

  key id            as BusinessPartnerID,  
      given_name    as GivenName,
      middle_name   as MiddleName,
      family_name   as FamilyName  

}

In addition to the projected entity (or) underlying CDS view fields, you can also add/expose new read-only elements using the keyword VIRTUAL.
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Projection View on Products'
@Metadata.allowExtensions: true
define view entity DEMO_PRD_PV_I_SL
  as projection on DEMO_PRD_CDS_I_SL
  {
    key node_key   as ProductGuid,
      product_id as ProductId,
      type_code  as CategoryCode,
      category,
      supplier_guid as SupplierGuid,
      tax_tarif_code as TaxTarifCode,
      price as Price,
      
      @ObjectModel.readOnly: true
      @ObjectModel.virtualElement: true
      @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_DEMO_CODE_EXIT'
      cast( '' as abap.char(4)) as Discount
  }

Consumption views are introduced for data modeling as part of the ABAP Programming Model for SAP Fiori.

Both Projection views and Consumption serve the same purpose to simply access of business objects. But with the new ABAP Restful Programming Model (RAP), projects views will be the future replacement for consumption views.

  • ABAP CDS projection views can not be used as a data source in other CDS entities.
  • They are allowed in ABAP programs as data type definitions and in ABAP SQL select statements.
  • Joins and subquery clauses are not allowed.
  • CDS projection views can’t directly access a DIDC database table and are always based on existing CDS view models.
  • CDS project views do not support Table buffering.
  • A CDS projection view can be extended using a CDS view extension.

ABAP CDS Custom entity

  • CDS View Entities Improved version of classic CDS DDIC-based views.
  • CDS Projection Views A direct projection of an underlying any CDS entity.
  • CDS Custom Entities They are used for data models whose runtime is implemented manually.
  • CDS Hierarchies Used to create a hierarchy from a data source.
  • CDS Table Functions Implemented using AMDP Class and functions.
  • CDS Abstract Entities Describes type attributes and database object instances are created.
  • CDS DDIC-based views Based DDIC based database views in ABAP Dictionary.
The runtime is implemented manually using the ABAP class.

ABAP CDS custom entities are non-SQL (or) no-SELECT CDS entities whose runtime is implemented manually by adding an annotation @ObjectModel.query.implementedBy. It requires an ABAP class that implements the select method of the interface IF_RAP_QUERY_PROVIDER.

@EndUserText.label: 'Display Supplier List'
@ObjectModel.query.implementedBy: 'ABAP:ZCL_SUPPLIER_LIST'
@Search.searchable: true

define custom entity ZCDS_C_SUPPLIER_LIST  
{
  key Supplier      : supplier_id;  
      CompanyCode    : bukrs;
      BusinessParnter : bu_partner;
      PruchasingOrganisation : ekorg;  
}

  • CDS custom entities do not have a SELECT statement.
  • The runtime of a CDS custom entity is implemented manually in an ABAP class ZCL_SUPPLIER_LIST
  • The class ZCL_SUPPLIER_LIST is referenced in the CDS custom entity using the annotation @objectModel.query.implementedBy.
  • The elements of the CDS custom entity are specified and separated by a semicolon. The final element must also be followed by a semicolon.
  • Optional, you can add input parameters to the custom entity.
Following the ABAP Class syntax for custom entity implementation. To complete the implementation the SELECT method of the query provider interface IF_RAP_QUERY_PROVIDER is refined with data retrieval logic.

Note: Before activating the CDS custom entity, we need to create an ABAP class that implements the interface IF_RAP_QUERY_PROVIDER. 

CLASS ZCL_SUPPLIER_LIST DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_rap_query_provider.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS ZCL_SUPPLIER_LIST IMPLEMENTATION.
  METHOD if_rap_query_provider~select.

   "abap code goes here to retrived the data...
  ENDMETHOD.

ENDCLASS.

The CDS custom entity is used to define data models whose runtime is implemented manually. The signature of the CDS entity is also separated from the implementation. The following are some of the use cases

Comments