Ansicht
Dokumentation

ABAPSHEET_ABAP_SQL_HIERARCHIES - SHEET ABAP SQL HIERARCHIES

ABAPSHEET_ABAP_SQL_HIERARCHIES - SHEET ABAP SQL HIERARCHIES

BAL Application Log Documentation   General Material Data  
Diese Dokumentation steht unter dem Copyright der SAP AG.
SAP E-Book

: Arbeiten mit Hierarchien

Dieser Spickzettel bietet eine Zusammenfassung der Möglichkeiten bei der Arbeit mit hierarchischen Daten aus Datenbanktabellen mit SQL in Kombination mit ABAP CDS. Bei hierarchischen Daten in Datenbanktabellen sind die Zeilen aus einer oder mehreren Datenbanktabellen durch Eltern-Kind-Beziehungen verbunden. Hierarchische Daten spielen in vielen Anwendungsfällen eine Rolle, wo der Zugriff auf Information über die hierarchische Beziehung relevant ist. In einem häufigen Fall beispielsweise müssen die Nachfahren oder Vorfahren eines gegebenen Hierarchieknotens ermittelt werden oder die Werte von Unterbäumen aggregiert werden.

Übersicht

Früher mussten die Daten aus der Datenbank in interne Tabellen manuell geladen und programmiert werden (wenn kein passendes API vorhanden war). Später boten Meshes einige Funktionen für die Arbeit mit Hierarchien, wie in diesem Beispiel gezeigt, werden aber nicht häufig verwendet.

Heutzutage ist die Standarddatenbank bei AS ABAP eine SAP HANA-Datenbank mit vielen hilfreichen Eigenschaften. U.a. wird dort eine Menge Hierarchiefunktionen angeboten, mit denen hierarchische Daten direkt auf der Datenbank behandelt werden können und in der SAP-HANA-Dokumentation beschrieben sind. Anders als vielleicht erwartet muss man auf diese Funktionen aus den ABAP-Programmen nicht über AMDP zugreifen. Mit ABAP SQL und ABAP CDS werden Hierarchien direkt unterstützt, in dem die eingebauten Funktionen ohne Performance-Verlust verschalt werden. Man bleibt dabei in der bequemen Welt des ABAP und hat trotzdem Zugriff auf die meisten modernen Funktionen. Man muss nur ein paar Konzepte kennenlernen und etwas neue Syntax lernen und dann ist man gleich startbereit.

SQL-Hierarchien

Der Begriff SQL-Hierarchie kennzeichnet eine hierarchische Datenquelle, die in der FROM-Klausel von ABAP-SQL-Queries verwendet werden kann. Eine SQL-Hierarchie ist eine tabellarische Menge Zeilen, mit denen die Hierarchieknoten einer Hierarchie gebildet werden und die zusätzliche Hierarchiespalten mit Hierarchieattributen mit hierarchiespezifischen Information für jede Zeile enthalten. Zum Anlegen einer SQL-Hierarchie ist Folgendes notwendig:

  • Datenquelle
Dies kann eine beliebige Datenquelle sein, auf die in einer ABAP-SQL-Query zugegriffen wird, meistens eine Datenbanktabelle oder CDS-View, aber CTEs (allgemeine Tabellenausdrücke) sind möglich. Mit der Struktur und Inhalt der Datenquelle sollten hierarchische Daten abbildbar sein.
  • Eltern-Kind-Beziehung
Es muss eine Eltern-Kind-Beziehung zwischen zwei oder mehreren Spalten der Datenquelle definiert werden. Aus der Eltern-Kind-Beziehung und den eigentlichen Daten der Datenquelle kann die SQL-Hierarchie aus Elternknoten und Kindknoten gebildet werden. Die Eltern-Kind-Beziehung muss durch eine Selbstassoziation definiert werden, die Hierarchieassoziation genannt wird. Dies kann durch CDS-Assoziationen oder CTE-Assoziationen erreicht werden. Eine Datenquelle, die eine Hierarchieassoziation exponiert, kann als Hierarchiequelle für das Anlegen einer SQL-Hierarchie verwendet werden.
  • Anlegen einer Hierarchie
Aus einer Hierarchiequelle, nämlich einer Hierarchieassoziation exponierenden Datenquelle, kann eine SQL-Hierarchie angelegt werden. Dies ist entweder durch die Definition einer CDS-Hierarchie außerhalb eines ABAP-Programms oder durch den ABAP-SQL-Hierarchiegenerator direkt in der FROM-Klausel einer ABAP-SQL-Query innerhalb eines ABAP-Programms möglich.

In folgenden Abschnitten wird man schrittweise durch das Anlegen von SQL-Hierarchien geführt und wie man darauf zugreift.

Anlegen von SQL-Hierarchien

ABAP-CDS-Hierarchien

In CDS-Hierarchien wird die Hierarchiedatenquelle und das Anlegen der SQL-Hierarchie aus dem ABAP-Programm ins ABAP CDS übertragen. Dort ist die Hierarchie eine vollständig ausgebaute CDS-Entität, die in anderen Programmen oder in anderen CDS-Entitäten (Views) wiederverwendbar ist und zum Teil des Datenmodells einschließlich der Zugriffskontrolle über CDS DCL wird. Bei einer CDS-Hierarchie kann eine Hierarchiequelle ausschließlich eine CDS-View sein, die eine Hierarchieassoziation exponiert. Ein sehr einfaches Beispiel:

Diese CDS-View-Entität greift auf die Datenbanktabelle DEMO_SIMPLE_TREE mit den eigentlichen Daten zu und exponiert eine Selbstassoziation _tree. Mit der ON-Bedingung der Assoziation wird eine Eltern-Kind-Beziehung zwischen den Elementen id und parent definiert. Damit wird ausgedrückt, dass eine Zeile der Ergebnismenge, in der die Spalte parent den gleichen Wert wie die Spalte id einer anderen Zeile hat ein Kind der letzteren Zeile in der aus dieser View gebildeten Hierarchie ist. Mit der CDS-View wird auch eine andere Spalte name der Datenbanktabelle exponiert, die den restlichen Dateninhalt darstellt. Solche CDS-Views dürfen für eine beliebige Datenquelle definiert werden und die ON-Bedingung kann komplexer sein als in diesem einfachen Beispiel dargestellt wird.

Die CDS-View oben kann nun als Hierarchiequelle einer wie folgt definierten CDS-Hierarchie:

Die im DDL-Quelltexteditor der ADT verwendbare CDS-DDL-Anweisung DEFINE HIERARCHY definiert eine CDS-Hierarchie als CDS-Entität, auf die der Zugriff in CDS-Views oder ABAP-SQL als SQL-Hierarchie möglich ist. Die wichtigsten Zusätze der Anweisung sind:

  • SOURCE zur Angabe der Hierarchiequelle, hier DEMO_CDS_SIMPLE_TREE_VIEW.
  • CHILD TO PARENT ASSOCIATION zur Angabe der Hierarchieassoziation, hier _tree.
  • START WHERE zur Definition der Wurzelknoten der SQL-Hierarchie, hier durch einen Eingabeparameter p_id dargestellt, die beim Zugriff auf die CDS-Hierarchie übergeben werden müssen.
  • SIBLINGS ORDER BY zur Definition einer Sortierreihenfolge für Geschwisterknoten neben der ohnehin verwendeten Sortierreihenfolge aus der Eltern-Kind-Beziehung.
  • Eine Elementliste { ... } zur Definition die Spalten einer SQL-Hierarchie, hier einfach alle Elemente der Hierarchiequelle.

Eine vollständige Beschreibung und alle anderen Zusätze sind im Abschnitt DEFINE HIERARCHY enthalten.

Beim Zugriff auf die CDS-Hierarchie werden alle Zeilen aus der ursprünglichen Datenquelle selektiert, in diesem Fall der Datenbanktabelle DEMO_SIMPLE_TREE, die die START WHERE-Bedingung erfüllen. Diese bilden die Wurzelknotenmenge der SQL-Hierarchie. Im einfachsten Fall existiert genau ein Wurzelknoten, aber mehrere sind möglich. Für jeden Wurzelknoten werden dann seine Nachfahren abgerufen. Jede Zeile aus der Datenbanktabelle, die die ON-Bedingung der Hierarchieassoziation wird nämlich der SQL-Hierarchie hinzugefügt. Dies wird für jeden Nachfahren ausgeführt bis alle Nachfahren ermittelt worden sind und das ist eigentlich alles. Mit weiteren Zusätzen von DEFINE HIERARCHY kann das Anlegen der SQL-Hierarchie verwaltet werden, beispielsweise ob mehrere Eltern erlaubt sind oder die Behandlung von Waisenknoten oder Zyklen.

Neben den Elementen der Hierarchie kann die Elementliste auch die unter Hierarchieattribute aufgeführten Hierarchieattribute enthalten. Die SQL-Hierarchie wird dann mit Spalten mit Information über die Rolle der aktuellen Zeile als Hierarchieknoten, beispielsweise der Hierarchierangliste oder Hierarchieebene, erweitert. Im Beispiel wurde auf das Hinzufügen solcher Elemente verzichtet, da ABAP-SQL dies beim Zugriff auf die CDS-Hierarchie implizit erledigt.

In einer ABAP-SQL-Query kann die SQL-Hierarchie verwendet werden, in dem die CDS-Hierarchie direkt als Datenquelle der FROM-Klausel verwendet wird:

Es wurden zwar keine Hierarchieattribute in der Elementliste der CDS-Hierarchie definiert, die unter Hierarchiespalten aufgeführten Hierarchiespalten können der SELECT-Liste der ABAP-SQL-Anweisung hinzufügt werden. Dies ist beim Zugriff auf eine SQL-Hierarchie im ABAP-SQL immer möglich. Es darf nun eine beliebige ID an die CDS-Hierarchie übergeben werden und das Ergebnis abgewartet werden. Wenn eine solche Zeile in der Datenbanktabelle ermittelt wird, werden die jeweiligen hierarchischen Daten abgerufen und zurückgegeben. Nach der Ausführung des Programms DEMO_SQL_HIERARCHIES zur Füllung der Datenbanktabelle mit zufällig erzeugten Daten kann das tabellarische Ergebnis untersucht werden. Wie erwartet kommen alle Elemente der SELECT-Liste als Spalten vor. Der Inhalt der Spalte NAME ist beliebig. Hier wird sie mit einer String-Darstellung des Pfades vom Wurzelknoten zum aktuellen Knoten für Demonstrationszwecke.

Aus der Perspektive der Sprache ABAP sind CDS-Hierarchien die bequemste Art SQL-Hierarchien zu verwenden. Weiter unten werden andere Methoden mit immer mehr ABAP beschrieben, bis schließlich gar kein CDS verwendet wird.

ABAP-SQL-Hierarchiegenerator HIERARCHY

Der ABAP-SQL-Hierarchiegenerator ist eine SQL-Funktion namens HIERARCHY, mit der eine SQL-Hierarchie im ABAP-Programm selbst definiert werden kann. Ein Beispiel sieht man unten:

ASSERT asql_cds_result = cds_result.

Falls das Beispiel bekannt vorkommt, wird eine ähnliche Syntax zur Definition der CDS-Hierarchie innerhalb der Klammerung HIERARCHY( ... ) und die Funktion ist genau gleich. Der Unterschied ist wie der Unterschied zwischen Joins in ABAP SQL und Joins in CDS-Views:

  • Bei ABAP SQL darf er in nur einem Programm verwendet werden.
  • Bei ABAP CDS darf er in mehreren Programmen oder in ganzen Datenmodellen verwendet werden.

Wir zeigen dies mit einer ASSERT-Anweisung. Es werden hier wieder Hierarchiespalten verwendet. Sie sind beim Zugriff auf eine SQL-Hierarchie, hier vom Hierarchiegenerator angelegt, implizit vorhanden.

Der ABAP-SQL-Hierarchiegenerator oben greift auf die gleiche Hierarchiequelle wie die CDS-Hierarchie, nämlich die CDS-View DEMO_CDS_SIMPLE_TREE_VIEW mit der die erforderliche Hierarchieassoziation _tree exponiert wird. Im folgenden Quelltextausschnitt wird die CDS-Hierarchiequelle mit einem CTE ersetzt:

ASSERT asql_cte_result = cds_result.

Allgemeine Tabellenausdrücke (CTEs) sind ein mächtiges Werkzeug zur Definition von Subqueries, die in folgenden Queries derselben WITH-Anweisung verwendet werden können. Sie können auch als interne ABAP-SQL-Definitionen von Datenquellen betrachtet werden, die die gleiche Funktion wie programmexterne Datenquellen, insbesondere CDS-Views, erfüllen. Wie oben hat der CTE cte_simple_tree_source die gleiche Funktion wie die CDS-View DEMO_CDS_SIMPLE_TREE_VIEW:

  • Hiermit wird auf die Datenbanktabelle DEMO_SIMPLE_TREE zugegriffen.
  • Es wird durch Verwendung des Zusatzes WITH ASSOCIATIONS eine Assoziation _tree exponiert.

Die Haupt-Query der WITH-Anweisung verwendet den Hierarchiegenerator wie bei SELECT oben, aber mit dem CTE als Datenquelle statt der CDS-View. Das Ergebnis ist natürlich gleich.

Eine vollständige Beschreibung des Hierarchiegenerators und von allen anderen Zusätzen ist unten SELECT, FROM HIERARCHY enthalten.

Man hat nun eine SQL-Hierarchie ausschließlich mit ABAP-SQL-Mitteln angelegt. Letztendlich werden CTEs selbst als Hierarchien verwendet. Wenn die syntaktischen Feinheiten nicht vom Interesse sind, sondern die Hierarchienavigatoren, darf der nächste Abschnitt übersprungen werden.

ABAP-CTE-Hierarchien

Ein CTE, der hierarchische Daten erzeugt darf sich über den Zusatz WITH HIERARCHY selbst als SQL-Hierarchie mit frei definiertem Namen deklarieren. Das heißt einfache, dass folgende Queries derselben WITH-Anweisung darf den CTE als Hierarchie mit seinen impliziten Hierarchiespalten, oder noch wichtiger in Hierarchienavigatoren.

In folgenden Quelltextausschnitten wird dreimal gezeigt, wie ein CTE hierarchische Daten erzeugen kann:

ASSERT cte_cds_result  = cds_result.
ASSERT cte_asql_result = cds_result.
ASSERT cte_cte_result  = cds_result.

Ein als SQL-Hierarchie exponierter CTE muss selbst auf eine SQL-Hierarchie zugreifen und diese haben letztendlich immer eine CDS-Hierarchie oder den ABAP-SQL-Hierarchiegenerator wie oben als Grundlage. Die Hierarchiequelle des Hierarchiegenerators kann eine CDS-View oder ein die Hierarchieassoziation exponierender CTE sein. Bei Ausführung von DEMO_SQL_HIERARCHIES werden alle Zusätze erfüllt.

Hierarchienavigatoren

Hierarchienavigatoren sind eine zusätzliche Menge von ABAP-SQL- Hierarchiefunktionen, mit denen keine neuen SQL-Hierarchien angelegt werden müssen, sondern existierende SQL-Hierarchien verarbeitet werden können. Hierarchienavigatoren können SQL-Hierarchien wie oben angelegt behandeln, nämlich CDS-Hierarchien, den Hierarchiegenerator oder die CTE-Hierarchie. Sie können als Datenquellen in ABAP-SQL-Queries verwendet werden. Falls eine SQL-Hierarchie mehrfach verwendet werden soll, soll sie einmal mit einer gegebenen Wurzelknotenmenge angelegt werden und nachher soll aus Performancegründen der Zugriff mit Hierarchienavigatoren erfolgen. Darüber hinaus kann die Ergebnismenge durch jeden Hierarchienavigator um weitere Hierarchiespalten erweitert werden, die weiter Auswertungsmöglichkeiten anbieten.

In den folgenden Beispielen wird mit Hierarchienavigatoren auf die CDS-Hierarchie zugegriffen. Sie könnte aber auch durch den Hierarchiegenerator oder eine CTE-Hierarchie ersetzt werden. Beispiele davon sind auch in dieser Dokumentation zu finden.

Hierarchieknotennavigator HIERARCHY_DESCENDANTS

Wie aus dem Namen ersichtlich ruft HIERARCHY_DESCENDANTS alle Nachfahren für beliebige Knoten aus einer SQL-Hierarchie. Hiermit wird die Ergebnismenge um HIERARCHY_DISTANCE als zusätzliche Ergebnismenge erweitert. Ein Beispiel sieht man unten. Alle Beispiele bestehen wieder aus Quelltextabschnitten aus DEMO_SQL_HIERARCHIES.

Mit der CDS-Hierarchie DEMO_CDS_SIMPLE_TREE_VIEW wird eine SQL-Hierarchie angelegt und ein Startknoten an p_id übergeben. Alle Nachfahren werden für einen Knoten sub_id abgerufen. Wenn das Programm ausgeführt wird, wird das Ergebnis mit der zusätzlichen Spalte HIERARCHY_DISTANCE mit dem Abstand zum jeweiligen Startknoten gezeigt. Ein weiterer nicht gezeigter Parameter DISTANCE schränkt den Abstand zum jeweiligen Startknoten ein.

Hierarchieknotennavigator HIERARCHY_ANCESTORS

Nun in der umgekehrten Richtung gibt die ABAP-SQL-Funktion HIERARCHY_ANCESTORS die Vorfahren eines beliebigen Knotens einer existierenden Hierarchie zurück:

Das Ergebnis der Ausführung von DEMO_SQL_HIERARCHIES zeigt nun einen negativen Wert der Spalte HIERARCHY_DISTANCE. Mit Aggregatfunktionen oder Auswertungen der internen Ergebnistabelle kann man weitere Information wie die Anzahl Vorfahren abrufen.

Hierarchieknotennavigator HIERARCHY_SIBLINGS

Neben Nachfahren und Vorfahren können Hierarchieknoten auch Geschwister haben, nämlich Knoten mit demselben Elternknoten. Diese können durch eine Suche nach allen Knoten mit dem gleichen Wert in der Hierarchiespalte HIERARCHY_PARENT_RANK. Mit der Hierarchiefunktion HIERARCHY_SIBLINGS kann dies auch erreicht werden:

Diese Funktion fügt eine andere Hierarchiespalte HIERARCHY_SIBLING_DISTANCE mit dem Abstand zum jeweiligen Startknoten hinzu. Die Ausführung von DEMO_SQL_HIERACHIES, wo ein Knoten definitiv Geschwister hat, zeigt das Ergebnis.

Hierarchieaggregatnavigatoren

Zum Schluss werden die Hierarchieaggregatnavigatoren dargestellt, die einige Aggregatfunktionen auf Vorfahren und Nachfahren eines beliebigen Knotens in einer SQL-Hierarchie anwenden.

Es wird ein Beispiel für die Nachfahren gezeigt und auf die Dokumentation für die Vorfahren hingewiesen.

Die Anwendung von Aggregatfunktionen auf Spalten erfordert normalerweise sinnvolle Daten. Im hier verwendeten SQL-Hierarchiebaum stehen solche Daten nicht zur Verfügung. Ein möglicher Anwendungsfall ist dies trotzdem: Die Verwaltungsdaten für die Eltern-Kind-Beziehung kann in einer Datenbanktabelle vorhanden sein und die echten Daten in einer anderen Tabelle. In diesem Anwendungsfall bietet der Hierarchieaggregatnavigator HIERARCHY_DESCENDANTS_AGGREGATE die Möglichkeit einer Verknüpfung solcher Daten mit der SQL-Hierarchie:

In diesem Beispiel wird eine interne Tabelle value_tab desselben Programms mit der SQL-Hierarchie verknüpft. In einem echten Beispiele würde natürlich eine andere Datenbanktabelle verknüpft werden. Im Beispiel wird die Fähigkeit vom ABAP SQL demonstriert, interne Tabellen als Datenquellen zu verwenden. Es ist sogar möglich, durch die Verwendung einer internen Tabelle als Datenquelle für eine CTS-Hierarchie hierarchische Daten in internen Tabellen mit ABAP SQL auszuwerten.

Das Beispiel demonstriert folgendes:

  • Der Hierarchieaggregatnavigator HIERARCHY_DESCENDANTS_AGGREGATE wird als Datenquelle einer FROM-Klausel verwendet.
  • Die mit der internen Tabelle value_tab verknüpften CDS-Hierarchie DEMO_CDS_SIMPLE_TREE_VIEW wird als Datenquelle verwendet.
  • Mit der ABAP-SQL-Funktion wird ein tabellarisches Ergebnis von Knoten der Datenquelle zurückgegeben.
  • Mit der Aggregatfunktion SUM hinter MEASURES werden die Werte der Spaltenbeträge der verknüpften internen Tabelle für alle Nachfahren jedes von der ABAP-SQL-Funktion zurückgegeben Knotens summiert.
  • Mit der WHERE-Bedingung wird die Ergebnismenge durch eine frei programmierbare Bedingung eingeschränkt.
  • Mit den WITH-Zusätzen werden weitere durch ihre Werte in einer zusätzlichen Hierarchiespalte HIERARCHY_AGGREGATE_TYPE erkennbare Zeilen der Ergebnismenge hinzugefügt:
  • WITH SUBTOTAL

In der Zeile mit HIERARCHY_AGGREGATE_TYPE gleich 1 enthält die Spalte AMOUNT_SUM die Summer der Werte aller Hierarchieknoten, die die WHERE-Bedingung erfüllen.
  • WITH BALANCE

In der Zeile mit HIERARCHY_AGGREGATE_TYPE gleich 2 enthält die Spalte AMOUNT_SUM die Summer der Werte aller Hierarchieknoten, die die WHERE-Bedingung nicht erfüllen.
Weitere WITH-Zusätze sind in der Dokumentation enthalten.

Die Ausführung von DEMO_SQL_HIERARCHIES zeigt das Ergebnis. Es wird auch das Ergebnis der verknüpften Datenquelle gezeigt und es kann die Korrektheit der berechneten Werte überprüft werden.

Arbeiten mit Hierarchien

Die vollständige Referenzdokumentation über SQL-Hierarchien ist unter SELECT, FROM hierarchy_data enthalten.






Fill RESBD Structure from EBP Component Structure   rdisp/max_wprun_time - Maximum work process run time  
Diese Dokumentation steht unter dem Copyright der SAP AG.

Length: 26483 Date: 20240523 Time: 142050     sap01-206 ( 431 ms )