Das perfekte SAP BW Expertenskript

Release SAP BW 7.4 SP11, SAP HANA SPS 98, BW-MT 1.11

Ich hatte bereits einen Beitrag über SAP HANA Expertenskript geschrieben, der sich eher inhaltlich mit den Vorteilen auseinander gesetzt hat. Nun möchte in noch unter SAP BW Transformationen einen technischen Part hinzufügen.

Mit der SAP Business Warehouse, powered by SAP HANA oder spätestens BW4/HANA hat eine wunderbare Funktionalität seinen Weg ins SAP BW gefunden: Das Expertenskript. In der neuesten Version von SAP BW 7.5 sogar verwendbar statt Start- und oder Endroutine mit verbesserten Error Handling und Debugging.

Die SAP empfiehlt seit einiger Zeit die Verwendung von Standardfunktionalitäten innerhalb des SAP BW mit der Begründung, dass diese (größtenteils) in der SAP HANA ausgeführt werden und dadurch einen massiven Gewinn an Performance erfahren. Wir erinnern uns: Code Push-Down soll gut sein (Warum es gut sein soll erkläre ich noch bald in einem anderen Beitrag). Mal abgesehen davon, dass immerhin ein Großteil an Standardfunktionalität nun auch in der SAP HANA ausgeführt werden kann (dazu gehört nicht ABAP) und hier und da noch ein kleiner Bug ist (komische SQL Fehlermeldungen im SAp BW). Das Schöne am SAP BW ist doch das kundeneigene Transformieren von Daten!

Wenn man dies machen will, empfehle ich das Expertenskript. Vorab sei verraten, dass man sich zwangsläufig mit SQL auseinander setzen muss und sollte. Ich versuche im nachfolgenden Beispiel alles so einfach wie möglich zu halten.

Die Bearbeitung des Expertenskript erfolgt im SAP HANA Studio, welches spätestens seit den neuen InfoProvidern und allerspätestens mit BW4/HANA die neue RSA1 darstellt. Es ist zunächst gewöhnungsbedürftig, aber man kann sich gut orientieren.

Vom Adaptieren und Anwenden

Innerhalb des Expertenskriptes gibt es eine inTab und eine outTab. Vergleichbar mit source_package und result_package. Das heißt im einfachst Fall kann ich einfach

outTab = SELECT * FROM :inTab;

in das Expertenskript einfügen und wäre fertig. Vorausgesetzt die Struktur von inTab entspricht der Struktur von outTab. In den meisten Fällen tut sie das aber nicht, korrekt wäre als in etwa sowas wie

outTab = SELECT "/BIC/ZFELD1", "MATERIAL", " " AS "/BIC/ZFELD2" FROM :inTab;

Hier nehmen wir das InfoObjekt ZFELD1 und 0MATERIAL aus der inTab und zusätzlich definieren wir ein leeres CHAR Feld als ZFELD2 in die Zielstruktur. Die inTab kann offensichtlich auch nur ein Teil der Felder für das Ziel outTab enthalten. Über das SELECT wählen wir generell die Felder für die Zielstruktur aus.

Achtung! Im Expertenskript kommen technische Felder mit. Scrollt man im Expertenskript etwas weiter nach oben, sieht man auch die Stukturdefinitionen von inTab und outTab. So kann man es sich angewöhnen die Reihenfolge von outTab einzuhalten und zusätzlich Felder wie RECORDMODE und RECORD zu berücksichtigen.

Vom Erweitern und Transformieren

Nun ist es nicht zielführend einfach leere Felder in die Zielstruktur zu übergeben, sondern ein Feld aus einer anderen Tabelle (der häufigste und einfachste Fall) hinzuzufügen. Es gibt hierzu zwei Vorgehensweisen:

  • Variante 1: Ich erweitere das obige SELECT um einen INNER/OUTER JOIN und füge das Feld aus einer zweiten Tabelle hinzu.
  • Variante 2: Ich lese in einem separaten SELECT die Information nach und erweitere den obigen Join darüber. Quasi eine Art Modulaisierung.

Für einzelne Tabellen mag Variante 1 charmant sein, aber ich empfehle von Anfang an Variante 2. Selten liest man nur eine Information nach, sondern hat Abhängigkeiten, Regeln und viele Mappings. Und da mach es Variante 2 wesentlich einfacher die Übersicht zu behalten.

Achtung! Aus Tabellen nachlesen nie über die DDIC Tabelle, sondern über den Analytical/Calculation View eines InfoProviders. Jeder InfoProvider hat in den Meta ein Häkchen für „Externen SAP-HANA-View“ versteckt. Aktiviert man diesen, so generiert das SAP BW einen eigenen Analytical/Calculation View.

Doch wie sieht nun Variante 2 aus anhand des Beispiels von oben. Wir nehmen an, dass wir aus dem Material eine zusätzliche Information lesen wollen (und nicht die Standardfunktionalität „Stammdaten nachlesen“ nutzen wollen), dann erstelle ich zu 0MATERIAL einen externen SAP-HANA-View und lese in eine temporäre Tabelle meine Zusatzinformation!

lt_material = SELECT
it."MATERIAL",
material."MAT_GRP"
FROM :inTab AS it
LEFT OUTER JOIN "_SYS_BIC"."system-local.bw.bw2hana/MATERIAL" AS material
ON it."MATERIAL" = material."MATERIAL";

Ich halte mich bei der Notation an dem was ich kenne aus dem ABAP. Generell ist die vorgehendweise dem ABAP ziemlich ähnlich. So fülle ich auch hier eine lokale Tabelle über den Schlüssel mit den relevanten Informationen. Das mache ich für jede Information die ich benötige in einer eigenen temporären Tabelle im Expertenskript. Das erhöht die Übersichtlichkeit ungemein und zusätzlich erreicht man eine optimale Parallelisierung der SELECT, welche die SAP HANA bei der Laufzeit automatisch ausführt.

Achtung! Das LEFT OUTER JOIN liefert immer ein MAT_GRP zurück, d.h. auch dann wenn kein MATERIAL zu finden ist. Es wird dann allerding kein Leerwert geliefert, sondern ein NULL. Das NULL ist ein eigener Wert, welcher allerdings vom SAP BW nicht erkannt wird. D.h. wenn ich ein NULL über die outTab an das SAP BW übergebe, dann funktioniert die Transformation nicht. Daher empfehle ich die Funktion IFNULL und das NULL durch einen Leer-, Fehler- oder alternativen Wert zu ersetzen. Das schont Zeit und Nerven.

Letztendlich führe ich am Ende alle Ergebnisse in meine outTab zusammen

outTab = SELECT
it."/BIC/ZFELD1",
it."MATERIAL",
" " AS "/BIC/ZFELD2",
material."MAT_GRP"
FROM :inTab AS it
LEFT OUTER JOIN :lt_material AS material
ON it."MATERIAL" = material."MATERIAL";

Wobei ich für jede zusätzliche Information ein erneutes LEFT OUTER JOIN ausführe.

Zusammenfassung

Das Beispiel soll eine einfach Einführung sein und verdeutlichen, dass die „neue Welt“ nicht so kompliziert ist. Das Beispiel gibt auch so nicht viel Sinn, da ich eher die Standardfunktionalität nutzen würde. Allerdings bietet das SQL nicht nur SELECT und JOIN, sondern sehr viele Funktionalitäten auf Feldebene. Ein Beispiel wäre CASE, das IF im SQL. Oder MIN, MAX Funktionalitäten als Möglichkeit der Aggregation.

Im Prinzip habe ich bereits ganze ABAP Routinen in Expertenskript (SQL) umgeschrieben, ohne Probleme. Man muss nur etwas umdenken, da man in einem SQL generell die Dinge anders angeht. Man sollte aber stets seine Kollegen mitnehmen und die Themen, Best Practices etc. gemeinsam vorantreiben. Auch empfehle ich von anfang an Namensrichtlinien zu erstellen oder aus dem ABAP zu übernehmen bzw. Richtlinien zu erstellen, ab wann Expertenskripte zum Einsatz kommen (Performance z.B.).

Falls noch mehr gewünscht ist, eventuell auch als eigene Podcast Episode, so kann man gerne Kommentare hinterlassen oder das Kontaktformular verwenden.

 

Post a Comment

*