CDS - Join, Union
Im heutigen Artikel schauen wir uns einmal die Verknüpfung von Daten und Views an und wie du daraus neue Datenmengen generieren kannst.
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.
Bei bisherigen Beispielen haben wir uns immer auf eine Entität und deren Daten beschränkt, diese haben wir schon um neue Felder und Inhalte ergänzt. Dies ist aber nur ein Aspekt von CDS Views, ein anderer ist die Verknüpfung von Datenmengen zu größeren Views.
Join
Wenn du in der Vergangenheit schon einmal verschiedene Datenquellen in eine Ausgabetabelle überführt hast, dann standen verschiedene Wege zur Verfügung um dies zu tun. Es gab die Möglichkeit die Tabellen einzeln Einzulesen und dann per Loop in eine gemeinsame Struktur zu überführen. Oder du hattest dich gleich für einen Join entschieden, der dann eine gewisse Größe im Programm erreicht hat. Doch was hast du gemacht, wenn du den gleichen Zugriff vielleicht noch einmal an einer anderen Stelle benötigt hast? Wahrscheinlich hast du den Join in das nächste Programm kopiert, oder diesen in eine wiederverwendbare Klasse ausgelagert.
Heute können wir solche wiederverwendbaren Zugriffe als Core Data Services abbilden und durch die verschiedenen Ebenen einzelne Views in unterschiedlichen Szenarien abbilden. Bei den verwendeten Joins kannst du auf alle Joins (Inner, Left, Right, Outer) zugreifen, was mit den klassichen SAP Views nicht möglich war. Dazu einmal ein Beispiel:
@AbapCatalog.sqlViewName: 'ZBSIDMOCOMPDOC'
@EndUserText.label: 'Complete Invoice Document'
define view ZBS_I_DmoCompleteDocument
as select from ZBS_I_DmoPosition as Position
inner join ZBS_I_DmoInvoice as Head on Head.DocumentNumber = Position.DocumentNumber
inner join ZBS_I_DmoPartner as Partner on Partner.PartnerNumber = Head.PartnerNumber
{
key Position.DocumentNumber,
key Position.PositionNumber,
Head.PartnerNumber,
Partner.PartnerName,
Partner.City,
Partner.Country,
Position.MaterialNumber,
Position.PositionQuantity,
Position.PositionPrice,
Position.PositionCurrency,
Head.DocumentDate
}
Als Grundlage nehmen wir die Positionstabelle und lesen Informationen zum Kopf und zum Partner nach. Im Anschluss definieren wir noch einen Schlüssel, der die Ergebnismenge repräsentiert. Im Data-Preview von Eclipse können wir uns die Vorschau zu den Daten ansehen:
Den Core Data Service können wir nun in einem SELECT in einem Programm verwenden, ohne einen komplexen Join aufzubauen.
" Join CDS
SELECT FROM zbs_i_dmocompletedocument
FIELDS documentnumber, partnername, country, positionprice, positioncurrency
WHERE positionnumber = 1
ORDER BY documentnumber
INTO TABLE @DATA(lt_full)
UP TO 20 ROWS.
Analyse
Für die Analyse von Beziehungen und Verknüpfungen hilft der "Dependency Analyzer", diesen findet du im View "CDS Navigator" als eigener Button. Damit kannst du den aktuell gewählten Core Data Service analysieren, wenn du die Funktion wählst.
SQL Dependency Tree
In dieser Ansicht siehst du die Beziehungen der Views und Tabellen untereinander, ebeso wir die Daten zusammengeführt werden. Zusätzliche Informationen von Viewnamen und Entitätsnamen erhältst du hier ebenfalls.
SQL Dependency Graph
Dieser View schlüsselt die Quelle unseres Core Data Service bis zur Datenbank auf. Über die Hierarchie kannst du mit Rechts-Klick die entsprechenden Objekte im Editor öffnen.
Complexity Metrics
An dieser Stelle erhältst du Informationen zur Komplexität deiner Views und der Beziehungen die darunter liegen. Die Informationen können einen besseren Aufschluss zur Performance beim Laden der Daten geben.
Union
Eine besondere Form des Joins ist der Union, damit können zwei Datenmengen zu einer neuen Menge zusammengefügt werden. Dabei werden die Daten in eine einheitliche Struktur überführt und als gemeinsame Quelle genutzt. In unserem Beispiel nehmen wir den View vom letzten Artikel als Grundlage für den Union:
@AbapCatalog.sqlViewName: 'ZBSIDMOUNION'
@EndUserText.label: 'Union example'
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,
0.0 as PositionPrice,
PositionCurrency
}
where
ErrorInConversion = 'X'
Dabei erzeugen wir in der ersten Datemenge alle Rechnungen die in Ordnung sind und setzen den PositionType auf "Normal". Über die Where-Bedingung ermitteln wir nur Datensätze die keinen Fehler in der Konvertierung haben. Die zweite Datenmenge enthält die fehlerhaften Positionen, deren Preis auf Null gesetzt ist. Dazu ein kleiner Select um ein paar Belege einzulesen:
" Union Select
SELECT FROM zbs_i_dmounion
FIELDS *
WHERE documentnumber BETWEEN '30000010' AND '30000020'
ORDER BY documentnumber, positionnumber
INTO TABLE @DATA(lt_union).
Die ermittelten Daten lassen wir als Beispiel in die Console von Eclipse ausgeben, das Ergebnis könnte also wie folgt aussehen:
Hinweis: Hierbei handelt es sich um ein Beispiel mit der gleichen Tabelle, dies könnte auch mit einem CDS View ohne Union gelöst werden.
Fazit
Das neue virtuelle Datenmodell bietet vielfältige Funktionen um die Daten View für View zusammenzubringen und doch eine wiederverwendbare Grundlage zu bieten. Die Interface Views dienen hierbei als Grundlage und die normalisierten Felder als Grundlage des ganzen Modells.