Cheat Sheet CDS ABAP

Cheat Sheet CDS ABAP

Die perfekte Ergänzung zu den Schulungen von Brandeis Consulting

Dieser Spickzettel enthält eine umfassende Übersicht über Syntax, Beispiele und Beschreibungen zu CDS ABAP. Wir verwenden diese auch in unserer CDS ABAP Schulung bei Brandeis Consulting.

Diese Übersicht zeigt nur die wichtigsten Aspekte und ist nicht komplett. Für Details bitte den Links zur SAP Dokumentation oder den verlinkten Quellen folgen. Die Beispiele beziehen sich auf die Folien aus der Schulung.

Bei CDS ABAP spielt grundsätzlich das Release des ABAP Servers eine große Rolle, da hier noch viel in Bewegung ist. Die Beispiele wurden auf Release 7.58 (S/4HANA 2023) erstellt. Bei einem Blick in die Dokumentation sollten Sie stets exakt Ihren Versionsstand wählen.

Cheat Sheet online

CDS View Entities und CDS Views

Mit ABAP 7.55 hat die SAP die CDS View Entities veröffentlicht. Damit wurden die bisherigen CDS Views zu DDIC-based CDS Views umbenannt und diese sind seit 7.57 auch obsolet.

Unterschiede in CDS View Entities:

  • Es werden keine DDIC-View mehr generiert
  • Es gibt genau einen Namen für die Datei, das CDS Objekt und den SQL-View
  • Es gibt mehr Features in den SQL-Ausdrücken
  • Überflüssige Prüfungen wurden entfernt
  • Die Annotation @AbapCatalog.sqlViewName entfällt
  • Statt DEFINE VIEW heißt es DEFINE VIEW ENTITY

CDS Views vs. CDS View Entities

Empfehlungen

  • Neue Objekte nur noch als CDS View Entity implementieren
  • Bestehende CDS Views beibehalten

Syntax Grundlagen

Bezeichner von Tabellen, Views oder Spalten sind nicht case-sensitive. Sie dürfen maximal 30 Zeichen lang sein und bestehen aus Buchstaben, Zahlen, Unterstrichen und Schrägstrichen.

Zeichenliterale kommen in Hochkommata. Numerische Literale einfach hinschreiben, ggf. mit Dezimalpunkt.

Kommentare können entweder am Zeilenende mit einem doppelten Schrägstrich // beginnen oder als Blockkommentare zwischen /* und */ platziert werden.

Whitespace spielt keine große Rolle und dient in erster Linie zum Formatieren, solange die Semantik eindeutig ist.

Punkte werden zwischen Tabellennamen (auch Alias) und Feldnamen verwendet. z.B. mara.matnr.

Annotationen

Mit Annotationen wird der Quelltext um Meta-Informationen angereichert. Sie sind für die Konsumenten der CDS Objekte relevant. Jedes Framework hat seine eigenen Annotationen, z.B. :

  • @Analytics
  • @Consumtion
  • @ObjectModel
  • @OData
  • @UI

Hier sind nur zu wenigen Themen eine Auswahl von Annotationen erwähnt. Die komplette Liste ist in der SAP Dokumentation.

Syntax der Annotationen

@Annotation: <value>
@Annotation.SubAnnotation.SubSubAnnotation: <value>
@Annotation: { SubAnnotation1: <value1>,
               SubAnnotation2: <value2> }

Werte einer Annotation

  • Literale: Freitext, manchmal auch Feldnamen oder Assoziationen
  • Festwerte: mit # beginnend, Code-Completion nutzen!
  • Logische Werte true und false
  • Arrays: Liste von Werten oder SubAnnotationen, in eckigen Klammern mit Kommata getrennt

Syntaxübersicht CDS Views

DEFINE VIEW CDSEntity
  [...PARAMETER...]
  AS SELECT FROM <sources>
  [...JOIN..]
  [...ASSOCIATION..]
{
  [KEY] ... [ AS ... ]
  [,...]
} 
[WHERE ...]
[GROUP BY ...
  [HAVING ...]]
[UNION ...]

Ausdrücke in der Feldliste

Die Feldliste besteht aus Ausdrücken. Das sind meistens Feldnamen der Quellen. Es können aber auch andere Elemente darin vorkommen. Möglich sind:

Die Ausdrücke können ineinander geschachtelt werden. Beispielsweise kann ein Parameter als Vergleichswert in einem CASE - Ausdruck verwendet werden.

Die einzelnen Felder werden durch Komma getrennt. Falls sich nicht auf einen Feldnamen bezogen wird, ist ein mit AS vergebener Aliasname für das Feld Pflicht. Das Schlüsselwort KEY markiert den Schlüssel.

SQLScript Overview

Brandeis Consulting

Schulungen und Beratung vom Autor des Buches SQLScript für SAP HANA. Bei Fragen zur SQLScript, CDS ABAP oder unseren Schulungen einfach eine Mail an info@brandeis.de schicken.

© Brandeis Consulting GmbH

Datentypen in CDS ABAP und Casting

Die Typisierung in CDS bezieht sich entweder auf

  • Datenelemente des Data Dictionary
  • eingebaute ABAP Datentypen mit abap.<Type>
  • ab 7.57: CDS Simple Types oder CDS Enumerations

Die Datentypen werden an vielen Stellen streng geprüft und es gibt ggf. beim Aktivieren des CDS ABAP Objektes Fehlermeldungen. Zum Konvertieren der Datentypen dient die SQL-Funktion CAST:

CAST( <Expr> AS <Type> [PRESERVING TYPE])

Die ABAP Datentypen werden dabei mit abap.<Type> angegeben, also Beispielsweise

  • abap.int4
  • abap.char(<Length>)
  • abap.dec(<Length>, <Nachkommastellen>)

Je nach Datentyp muss die <Length> und ggf. auch die Anzahl <Nachkommastellen> in Klammern angegeben werden. Falls der Datentyp des <Expr> identisch mit dem angegebenen Datenelement ist (z.B. WAERS zu TRAN_CURR ), erleichtert der Zusatz PRESERVING TYPE das Lesen.

Session-Variablen

Es gibt eine Hand voll Session-Variablen, auf die man in CDS SQL mit dieser Syntax zugreifen kann:

$session.<Variablenname>

Bislang gibt es die folgenden Variablennamen, die weitgehend Komponenten der SY bzw. SYST Struktur im ABAP entsprechen:

  • USER – Der angemeldete ABAP Benutzer -SY-UNAME.
  • CLIENT – Der verwendende Mandant - SY-MANDT
  • SYSTEM _LANGUAGE – Die Anmeldesprache - SY-LANGU
  • SYSTEM _DATE – Aktuelles Systemdatum - SY-DATUM
  • SYSTEM _TIMEZONE – Zeitzone des Benutzers - SY-ZONLO
  • USER _DATE – Aktuelles Datum des Benutzers - SY-DATLO

Rechnen und Operatorausdrücke

In CDS ABAP funktionieren die Rechenoperatoren für Addition (+), Subtraktion (-), Multiplikation (*) wie man es erwarten würde. Grundsätzlich ist vor und nach dem Divisionsoperator (/) ein Whitespace notwendig. Die Berechnungen sind intern sehr genau. Beim CAST auf kleinere Datentypen werden Stellen abgeschnitten. Hier muss vorher mit der Funktion ROUND entsprechend gerundet werden.

CASE - Ausdrücke

Ein CASE - Ausdruck in CDS ABAP liefert je nach den Bedingungen immer genau einen Wert zurück. Der einfache CASE - Ausdruck vergleicht einen Ausdruck mit mehreren anderen Ausdrücken auf Gleichheit:

CASE item_categ WHEN '10' THEN 'A'
                WHEN '20' THEN 'B'
                ELSE 'C'
    END 

Der komplexe CASE - Ausdruck (engl. searched case) wertet N unabhängige Bedingungen aus. Die erste, die zu TRUE ausgewertet wird, liefert das Ergebnis:

CASE WHEN priority >= 9 THEN 'A'
     WHEN priority >= 6 THEN 'B'
     ELSE 'C'
   END 

Wenn keine Bedingung zu TRUE ausgewertet wurde, wird entweder der Wert aus der ELSE -Klausel oder NULL zurückgegeben.

Assoziationen

Assoziationen beschreiben die Beziehungen zwischen den CDS-Entitäten untereinander. Sie definieren einen JOIN, der nur bei Bedarf ausgeführt wird. Die Abfragen erfolgen mit sogenannten Pfadausdrücken und können über mehrere CDS-Entitäten hinweg erfolgen.

define view entity ZI_Users
  as select from zbc_users
  association of one to many to ZI_Tasks as _TasksToDo    
          on $projection.UserId = _TasksToDo.Assignee
	 
  association [0..*] ZI_Tasks as _TasksCreated 
          on $projection.UserId = _TasksCreated.Author
{
  key user_id   as UserId,
      firstname as Firstname,
      lastname  as Lastname,
      //      ...
      _TasksToDo,
      _TasksCreated
}

Die Namen der Assoziationen beginnen immer mit einem Unterstrich. Sie werden mit in die Feldliste aufgenommen und somit für die Nutzer des CDS-Views verfügbar gemacht.

Die Kardinalität kann in eckigen Klammern angegeben werden:

association [Min..Max] to ..., möglich sind 0, 1, *

Ab ABAP 7.58 kann man auch die folgende Syntax nutzen:

association of [many|one|exact one] to [many|one|exact one] ...

Je nach Framework haben Assoziationen unterschiedliche Wirkung

  • ABAP SQL - Lesen von Daten über Pfadausdrücke
  • Embedded Analytics - Verknüpfung von Dimensionen in Cubes
  • RAP - Komposition von Objekten und Navigation

Pfadausdrücke

Mit Pfadausdrücken können Felder aus assoziierten Views in die Feldliste des CDS Views oder der Abfrage auf die CDS Entität aufgenommen werden. Die Pfadausdrücke können auch über mehrere Views gehen. Und es ist möglich, entlang des Pfades zu filtern:

In CDS SQL

_TasksToDo.TaskKey,
_TasksToDo._Author.Lastname,
_TasksToDo[ Status = 'NEW' ].Summary,

In ABAP SQL

Die Pfadausdrücke können in ABAP SQL genutzt werden. Allerdings ist die Syntax etwas anders. Vor Assoziationen, und als Trennzeichen dazwischen, kommt immer der Backslash (\). Die Komponente wird, wie in ABAP üblich, mit dem Bindestrich (-) angesprochen:

\_TasksToDo\TaskKey,
\_TasksToDo\_Author.Lastname,
\_TasksToDo[ Status = 'NEW' ]-Summary,

NULL in CDS ABAP und ABAP

In der Datenbank gibt es den Pseudo-Wert NULL, der für die Abwesenheit eines Wertes steht. Dieser wird im ABAP in einen initialen Wert übersetzt. Das kann beim Aggregieren zu unerwarteten Situationen führen, da für NULL und Initialwert im CDS ABAP zwei Gruppen gebildet werden, die im ABAP aber beide initial sind.

Ersetzen von NULL

Mit der SQL-Funktion COALESCE(<Wert1>, <Wert2>) kann man NULL Werte abfangen, da diese dann den 2. Wert zurückgibt.

Filtern mit NULL

Ein normaler Vergleich mit NULL ergibt immer den logischen Wert UNKNOWN. Damit ist ein solcher Vergleich in der WHERE Bedingung niemals erfüllt. Deswegen muss das Prädikat IS (NOT) NULL verwendet werden.

SQL-Funktionen für Zeichenketten

Leerzeichen am Ende der Zeichenketten (<ZK>) werden in CDS SQL teilweise entfernt.

SQL functionDescription
CONCAT(<Str1>, <Str2>)Kombiniert <Str1> und <Str2>
CONCAT_WITH_SPACES( <Str1>, <Str2>, <Cnt>)Kombiniert <Str1> und <Str2> mit <Cnt> Leerzeichen
LENGTH(<Str>)Länge der Zeichenkette
LOWER(<Str>)In kleinbuchstaben
UPPER(<Str>)In GROSSBUCHSTABEN
LEFT(<Str>, <Len>)Linker Teil von <Str> mit <Len>
RIGHT(<Str>, <Len>)Rechter Teil von <Str> mit <Len>
SUBSTRING(<Str>, <Pos>, <Len>)Substring ab <Pos> mit <Len>
INSTR(<Str1>, <Str2>)Position von <Str2> in <Str1>
REPLACE(<Str1>, <Str2>, <Str3>)Ersetzt <Str2> in <Str1> mit <Str3>
REPLACE_REGEXPR(

PCRE => <Regex>,
VALUE => <Str>,
WITH => <Repl>,
RESULT_LENGTH => <Len>,
Optionale Parameter:
[OCCURRENCE],
[CASE_SENSITIVE],
[SINGLE_LINE],
[MULTI_LINE],
[UNGREEDY] )
Ersetzt die PCRE <Regex> im String <Str> mit dem <Repl>.

Parameter werden im Format Name => <Wert> übergeben.

OCCURENCE: 1-N oder ALL. Flags haben den Wert '' oder 'X'.
LPAD(<Str> , <Len> , <Pat>)Füllt <Str> von links mit <Pat> bis zur <Len> auf
RPAD(<Str>, <Len>, <Pat>)Füllt <Str> von rechts mit <Pat> bis zur <Len> auf
LTRIM(<Str> , <Char>)Entfernt führende <Char> in <Str>, z.B. Nullen oder Space
RTRIM(<Str>, <Char>)Entfernt rechts alle <Char> in <Str>

Numerische SQL-Funktionen

Kürzel: Zahl oder Zähler (<Z>), Nenner (<N>) und Nachkommastellen (<NK>).

SQL functionDescription
ROUND(<Z>, <NK>) Kaufmännische Rundung auf <NK> Stellen
CEIL(<Z>) Rundung auf...
FLOOR(<Z>) ...oder ab zur nächsten ganzen Zahl
DIVISION(<Z>, <N>, <NK>)<Z> dividiert durch <N>, gerundet auf <NK> Stellen
DIV(<Z>, <N>) Ganzzahliger Anteil der Division <Z> durch <N>
MOD(<Z>, <N>) Rest der Division <Z> durch <N> (Modulo)
ABS(<Z>) Positiver Absolutwert von <Z>
UNIT_CONVERSION Mengenumrechnung
CURRENCY_CONVERSIONWährungsumrechnung
DECIMAL_SHIFTDezimalverschiebung

Datums- und Zeitberechnung

Die SQL-Funktionen im CDS ABAP sind eine Teilmenge derer, die auch im OpenSQL in ABAP zur Verfügung stehen. Die Datentypen werden bei diesen SQL-Funktionen grundsätzlich vorangestellt, z.B.:

  • DATS ist der bekannte ABAP Datentyp, für die DB nur CHAR(8)
  • DATN ist das SQL-Datumsformat der HANA - für ABAP wenig relevant
  • TIMS ist der ABAP Datentyp für Zeit, für die DB nur CHAR(8)
  • TIMN ist das SQL-Zeitformat der HANA, siehe DATN
  • TSTMP ist der kurze Timestamp, 15-Stellige Dezimalzahl
  • TSTMPL ist der lange Zeitstempel mit 7 NK Stellen.
  • UTCL entspricht dem ABAP Datentyp UTCLONG, intern 8 Byte

Die Namen der CDS ABAP SQL- Funktionen beginnen mit dem Datentypen. Hier nur ein Auszug der wichtigsten Funktionen.

Konvertierungen

  • DATS_TIMS_TO_TSTMP
  • TSTMP_TO_DATS
  • TSTMP_TO_DST
  • TSTMP_TO_TIMS
  • TSTMPL_TO_UTCL
  • TSTMPL_FROM_UTCL

Addition

  • DATS_ADD_DAYS
  • DATS_ADD_MONTHS
  • TSTMP_ADD_SECONDS
  • UTCL_ADD_SECONDS

Differenzen

  • UTCL_SECONDS_BETWEEN
  • TSTMP_SECONDS_BETWEEN
  • DATS_DAYS_BETWEEN

Aktueller Zeitpunkt

  • UTCL_CURRENT
  • TSTMP_CURRENT_UTCTIMESTAMP
  • ABAP_SYSTEM_TIMEZONE
  • ABAP_USER_TIMEZONE

Parameter

Für einen CDS ABAP View können Parameter definiert werden, die dann als Ausdruck verwendet werden als

  • Argument beim Rechnen, z.B. Mehrwertsteuersatz,
  • Vergleichswert im WHERE, z.B. Sprache filtern oder
  • Funktionsparameter von SQL-Funktionen, z.B. Berichtswährung

Auf Parameter wird mit der $parameters Struktur zugegriffen

define view entity zi_Parameter
  with parameters 
    Vat      : abap.int1,
    Language : abap.lang,
    DisplayCurrency : abap.cuky( 5 )
    
  as select from <Table>
{
  key Task_key as Keyfield, 
      Amount * (1 + (100 + $parameters.Vat) 
                    / 100 ) as GrossAmount,
      currency_conversion( 
		  target_currency => $parameters.DisplayCurrency 
		  ... ) 
} where Language = $parameters.Language

CDS Extraktoren

Delta Extraktion mit Zeitstempelfeld

Das Delta wird über ein Zeitstempelfeld mit der Annotation @Semantics.SystemDateTime.LastChangedAt: true gebildet.

@Analytics:{ dataCategory: #CUBE
            dataExtraction:{
                enabled: true,
                delta.byElement: {   
                    name:'LastChangedAt'
} } }

Change Data Caption (CDC)

Automatische Änderungserfassung auf Systemen ab SAP S/4HANA 1909 FPS01 möglich. Bei komplexeren Szenarien mit JOINs muss explizit gemappt werden. Details im sehr lesenswerten Blog von Simon Kranig.

@Analytics:{
    dataCategory: #DIMENSION 
    dataExtraction: { 
        enabled: true, 
        delta.changeDataCapture: { 
            automatic : true 
} } }

CDS Table Functions

CDS Table Functions sind in SQLScript programmierte Views. Sie basieren auf einer AMDP-Funktion, die durch ein CDS ABAP Objekt gekapselt wird.

Überkreuz-Abhängikeit von CDS TF Definintion und ABAP-Klasse

Die CDS-Table Function definiert die Signatur:

@EndUserText.label: 'My Table Function'
DEFINE TABLE FUNCTION zjb_demo_tf
RETURNS
{
  mandt      : abap.clnt;
  doc_number : /bi0/oidoc_number;
  net_price  : /bi0/oinet_price;
}
IMPLEMENTED BY 
    METHOD zcl_demo_tf=>my_tf;

Die AMDP Tabellenfunktion dazu:

CLASS zcl_demo_tf DEFINITION PUBLIC.

  PUBLIC SECTION.
    INTERFACES if_amdp_marker_hdb.
    CLASS-METHODS my_tf 
        FOR TABLE FUNCTION zjb_demo_tf.
		
ENDCLASS.

CLASS zcl_demo_tf IMPLEMENTATION.

  METHOD my_tf BY DATABASE FUNCTION
           FOR HDB LANGUAGE SQLSCRIPT
           USING <sourceTable>.
    RETURN SELECT mandt,
                  doc_number,
                  SUM( net_price ) 
                         AS net_price
            FROM <sourceTable>
            GROUP BY doc_number;
  ENDMETHOD.  
ENDCLASS.

CDS InfoProvider Views

Basis für CDS Queries sind CDS InfoProvider mit der Annotation @Analystics.dataCateogory: [#CUBE | #DIMENSION]

Sie bilden einen transienten InfoProvider mit dem Namen 2C<SQLView Name>. Sie enthalten die vollständigen semantischen Informationen des Datenmodells, welches die CDS Queries später verwenden sollen.

CDS Cube Views

CDS Cube Views sind die Basis von Kennzahlenberichten. Sie können zusätzliche CDS Dimension Views assoziieren, um die Attribute und Texte von Merkmalen anzureichern.

@Analytics.dataCategory: #CUBE
DEFINE VIEW zjb_demo_cube
  AS SELECT FROM <Quelle>
  ASSOCIATION TO zjb_material_dim AS _Mat 
     ON $projection.material = _Mat.material
{
...
  @ObjectModel.foreignKey.association: '_Mat'
  material,
...
} 

CDS Dimension Views

Die CDS Dimension Views liefern Attribute zu einem Merkmal. Diese Attribute können zeitabhängig sein.

@Analytics.dataCategory: #DIMENSION
@ObjectModel.representativeKey: 'material'
DEFINE VIEW zjb_material_dim
  AS SELECT FROM /bi0/pmaterial AS dim 
  
  ASSOCIATION [*] TO zjb_mat_txt AS _MatText
         ON dim.material = _MatText.material
{
  @ObjectModel.text.association: '_MatText'
  KEY material,        
...
}

CDS Text Views

Die CDS Text Views liefern die sprachabhängigen Texte zu Feldern.

@ObjectModel.dataCategory: #TEXT
@ObjectModel.representativeKey: 'material'
DEFINE VIEW zjb_material_txt
  AS SELECT FROM /bi0/tmaterial 
{ 
  KEY material,
  
  @Semantics.language: true
  KEY langu,
  
  @Semantics.text: true
  txtmd 
}

CDS Query Views

Quelle für eine CDS Query View ist immer ein CDS InfoProvider View. Mit der CDS ABAP Annotation @Analytics.query: true wird aus einem View ein CDS Query View.

Annotationen auf Viewebene

@Analytics.query: true
@Analytics.settings.zeroValues: { 
  handling:   #HIDE_IF_ALL, //#HIDE, #SHOW
  hideOnAxis: #ROWS_COLUMNS//#COLUMNS,#ROWS
  }         

Annotationen auf Feldebene

Filter mit Prompt

@Consumption.filter:{
   selectionType: #RANGE,//#INTERVAL,#SINGLE
                         //#HIERARCHY_NODE 
   multipleSelections: false, 
   mandatory: true, 
   defaultValue: '0000000000011675' }

AnalyticDetails für Merkmale

@AnalyticsDetails.query:{
      display:       #KEY, //#KEY_TEXT,#TEXT
      axis:          #ROWS, //#COLUMNS
      totals:        #HIDE, //#SHOW
      sortDirection: #ASC } //#DESC     

AnalyticDetails für Kennzahlen

@AnalyticsDetails.query:{ 
                    decimals: 0 ,
                    hidden:  false
                    formula: ' a - b ' }
    1 AS a_minus_b,

@EndUserText.label: 'number of records' 
@AnalyticsDetails.exceptionAggregationSteps:
   [{ exceptionAggregationBehavior: #COUNT, 
    exceptionAggregationElements: 
                          ['doc_number'] }]
  1 AS doc_count