
CDS - Funktionen
In diesem Artikel beschäftigen wir uns mit den Funktionen im CDS Bereich und wie du sie vor allem einsetzen solltest, aber auch wobei sie dir helfen.
Inhaltsverzeichnis
Artikel-Update: Seit Release 7.57 (S/4 HANA 2022) ist DEFINE VIEW als obsolet gekennzeichnet, stattdessen solltest du DEFINE VIEW ENTITY verwenden. Diese können an einigen Stellen zu den Beispielen abweichen. Mehr Informationen zu den neuen Views findest du in diesem Artikel.
Im letzten Artikel hatten wir zusammen mit dir das Datenmodell aufgebaut und mit Daten befüllt. Heute bauen wir zusammen die ersten CDS Views und zeigen dir den Vorteil von Funktionen. Dabei werden wir auf einige wichtige Funktionen eingehen, aber nicht auf alle im Detail eingehen.
Code-Pushdown
Core Data Services können mehr als Daten in einem View zusammenzufügen und unter neuem Namen zur Verfügung zu stellen. Den großen Mehrwert erhält man durch die zahlreichen Funktionen die ABAP zur Verfügung stellt, um die Daten direkt auf der Datenbank zu ändern oder zu vergleichen. Der Einsatz der Funktionen direkt auf der Datenbank ist der sogenannte Code-Pushdown, da wir "Funktionen" an die Datenbank geben und nur noch das Ergebnis über die Datenbankschnittstelle erwarten.
CASE
In diesem Beispiel wollen wir einen Case nutzen, um alle fehlerhaften Positionen in unseren Datensätzen zu identifizieren. Dabei wollen wir dem Anwender nicht zutrauen, manuell nach einer fehlerhaften Zahl zu suchen, sondern wir wollen ein einfaches True/False zur Verfügung stellen, um die Einträge zu erkennen.
@AbapCatalog.sqlViewName: 'ZBSCDMOPOSERR'
@EndUserText.label: 'Positions with error'
define view ZBS_C_DmoPositionError
as select from ZBS_I_DmoPosition
{
key DocumentNumber,
key PositionNumber,
MaterialNumber,
PositionQuantity,
PositionPrice,
PositionCurrency,
case PositionPrice
when 37707 then 'X'
else ' '
end as ErrorInConversion
}
Der Case prüft den Inhalt eines Datenbankfeldes, dieses kann man mit verschiedenen When-Then Kombinationen abfragen und einen entsprechenden Wert setzen. Hinter Else kann man dann den Rest der nicht behandelten Feldinhalte abarbeiten. Die Kontrollstruktur wird mit End abgeschlossen und am Ende ein neues Feld definiert. Unter diesem Feldnamen kann das Feld dann angesprochen werden. Schauen wir uns dazu den Data-Preview in Eclipse an:
Das Feld "ErrorInConversion" wird entsprechend gesetzt und kann angesprochen werden, um so die Daten zu filtern. Beachte aber, dass du das neu erstellte Feld nicht für andere Funktionen oder in der Where-Kondition im View verwenden kannst.
CAST
Eine ebenso wichtige Funktion ist der CAST, damit kannst du Datentypen im CDS View ändern, ohne den eigentlichen Datentypen auf der Datenbank zu ändern. Damit können zum Beispiel prima Schnittstellenformate erzeugt werden, ohne eine Struktur extra dafür aufzubauen. Dazu einmal das folgende Beispiel:
@AbapCatalog.sqlViewName: 'ZBSCDMODISCAST'
@EndUserText.label: 'Cast from number'
define view ZBS_C_DmoDicountCast
as select from ZBS_I_DmoDiscount
{
key PartnerNumber,
key MaterialNumber,
DiscountValue,
concat( cast( DiscountValue as abap.char(15) ), ' %' ) as DiscountText
}
Hier verbinden wir die Cast Funktion mit einem Concat, um nach der Konvertierung auf Zeichenbasis noch ein " %" anzuhängen. Die Cast Funktion versucht die Konvertierung durchzuführen, weitere Details kannst der offiziellen Dokumentation entnehmen. Das Ergebnis der Konvertierung sieht nun wie folgt aus.
Session
Manchmal ist es sinnvoll auf den aktuellen User oder das aktuelle Datum zu prüfen und nur bestimmte Datensätze an den Aufrufer zu geben. Solche abhängigen Informationen werden in der Session zur Verfügung gestellt. Du kannst solche Session-Variablen als Felder, in On-Conditions oder Where Bedingungen verwenden. Die folgenden Variablen sind verfügbar:
Soll die Session Variable als Feld zur Verfügung gestellt werden, dann benötigt sie noch einen entsprechenden Alias, damit wird sie im View als Feld eingebunden. Genau so kannst du die Session nutzen, um über die Where Bedingung die Daten einzugrenzen. Als Beispiel der folgende View:
@AbapCatalog.sqlViewName: 'ZBSCDMOINVSESS'
@EndUserText.label: 'Session information'
define view ZBS_C_DmoInvoiceSession
as select from ZBS_I_DmoInvoice
{
key DocumentNumber,
DocumentDate,
$session.system_language as SystemLanguage
}
where
DocumentDate < $session.system_date
Schauen wir uns den Data-Preview an, dann sehen wir das gefüllte Feld "SystemLanguage" mit der aktuellen Anmeldesprache.
SUBSTRING
Hier noch eine Funktion zum Verarbeiten von Zeichenketten oder wie in unserem Beispiel für ein Datum. Wir wollen den Monat des Dokumenten-Datums extrahieren und als eigene Spalte zur Verfügung stellen. Dabei können wir die substring-Funktion nutzen, die du auch aus ABAP kennen solltest.
@AbapCatalog.sqlViewName: 'ZBSCDMOINVSUB'
@EndUserText.label: 'Substring for month'
define view ZBS_C_DmoInvoiceSubstring
as select from ZBS_I_DmoInvoice
{
key DocumentNumber,
DocumentDate,
substring( DocumentDate, 5, 2 ) as MonthInDocumentDate,
PartnerNumber
}
Das Ergebnis sieht nun wie folgt aus. Dabei solltest du allerdings beachten, dass das Ergebnis des Substring eine Zeichenkette ist und damit das Feld einen entsprechenden Datentyp hat. Willst du den Monat dann noch in eine Zahl konvertieren, dann kannst du das Ganze mit einem Cast verbinden.
Weitere Funktionen
In diesem Artikel wollten wir dir nur einmal ein paar Beispiele für Funktionen etwas näher bringen, es gibt noch viel mehr das du nutzen kannst. Hier mal ein paar weitere Beispiele:
- upper/lower - Konvertierung von Texten in klein/groß
- concat_with_space - Zusammenfügen mit Leerzeichen als Trenner
- coalesce - Ist der erste Wert null, dann wird der zweite Wert zurückgegeben
- dats_add_days - Tage auf ein Datum rechnen
- dats_days_between - Tage zwischen zwei Daten
Fazit
Durch den Einsatz von Funktionen hat die Datenbank mehr zu tun und wir vollziehen damit den Code-Pushdown. Die Operationen müssen nicht auf dem Applikationsserver durchgeführt werden, sondern du erhältst lediglich das Ergebnis der Abfrage.