Benutzerdefinierte Logik mit SQL entwickeln

Arbeiten mit SQLScript

Objective

After completing this lesson, you will be able to beschreiben Sie die zusätzlichen Funktionen von SQLScript im Vergleich zu Standard-SQL.

SQLScript-Funktionen

SQLScript ist eine von SAP entwickelte Datenbanksprache. Sie basiert auf Standard-SQL, fügt jedoch zusätzliche Funktionen hinzu, um die erweiterten Funktionen von SAP HANA Cloud zu nutzen.

Im Folgenden finden Sie einige der wichtigsten Funktionen von SQLScript:

  • SQLScript erweitert ANSI-92 SQL. Genau wie andere Datenbankanbieter SQL in ihren Datenbanken erweitern, erweitert SAP HANA SQL mit SQLScript.
  • Mit SQLScript können Sie auf SAP-HANA-spezifische Funktionen wie Spaltentabellen, parametrisierte Informationssichten, Delta-Puffer, die parallele Arbeit mit mehreren Ergebnismengen, integrierte Währungsumrechnungen auf Datenbankebene, Fuzzy-Textsuche, räumliche Datentypen und Predictive-Analytics-Bibliotheken zugreifen.
  • Mit SQLScript können Entwickler datenintensive Logik in die Datenbank übertragen.
  • SQLScript ermutigt Entwickler, Algorithmen mithilfe eines mengenorientierten Paradigmas zu pflegen, anstatt eines Datensatzes auf einmal.
  • SQLScript lässt jedoch eine Schleife über Ergebnisse und die Verwendung der If-Then-Else-Logik zu.
  • Mit SQLScript können Sie komplexe Abfragen in mehrere kleinere Anweisungen aufteilen und so Ihre SQL-Kodierung vereinfachen und die Parallelität über den Optimierer verbessern.

Notiz

Die Version von Standard-SQL, auf der SQLScript basiert, ist die beliebte ANSI-92-Version, die von fast allen Datenbanken unterstützt wird.

Zu den zusätzlichen Funktionen von SQLScript gehören die Arbeit mit SAP-HANA-Cloud-Spaltentabellen, die Übergabe von Parametern zwischen Calculation Views und SQLScript, die Arbeit mit räumlichen Datentypen und Predictive-Analysis-Bibliotheken.

Geschäftslogik mit SQLScript entwickeln

Bei herkömmlichen Client-Server-Ansätzen wird die Geschäftslogik im Anwendungsserver mithilfe von Programmiersprachen wie ABAP oder C++ definiert und ausgeführt. Mit SAP HANA Cloud kann ein Großteil dieser Logik nun mit SQLScript definiert werden, wodurch der Entwickler alle Datenverarbeitungsaufgaben in der Datenbank definieren und ausführen kann, um eine verbesserte Performance zu erzielen.

Mit SQLScript können Sie Variablen verwenden, um eine große komplexe SQL-Anweisung in kleinere, einfachere Anweisungen aufzuteilen. Dadurch wird der Code viel verständlicher. Sie hilft auch bei der Performance von SQL HANA Cloud, da viele dieser kleineren Anweisungen parallel ausgeführt werden können.

In diesem Video sehen Sie sich ein Beispiel an:

Im untersuchten Beispiel wollen wir herausfinden, welcher Verlag die meisten Bücher hat:

Code Snippet
12
books_per_publisher = SELECT publisher, COUNT (*) AS num_books FROM BOOKS GROUP BY publisher; publisher_with_most_books = SELECT * FROM :books_per_publisher WHERE num_books >= (SELECT MAX (num_books) FROM :books_per_publisher);

Der SQLScript-Compiler und der Optimierer bestimmen, wie diese Anweisungen am besten ausgeführt werden, indem ein allgemeiner Unterabfrageausdruck mit Datenbank-Hints verwendet oder in einer einzigen komplexen Abfrage kombiniert wird. Der Code wird einfacher zu schreiben und zu verstehen, ist wartbarer und die Entwicklerproduktivität steigt.

Indem Sie SQLScript in kleinere Anweisungen aufteilen und Tabellenvariablen füllen, spiegeln Sie auch die Art und Weise wider, wie Sie Ihre Calculation Views erstellt haben. Genau wie beim Erstellen von Calculation Views in Schichten, beginnend von unten nach oben, gehen Sie mit Ihrem SQLScript-Code genauso vor. Beachten Sie, dass die genaue Reihenfolge Ihrer SQLScript-Schritte nicht unbedingt die Laufzeitreihenfolge ist, da der Optimierer immer über den besten Ausführungsplan entscheidet. Der Optimierer ändert jedoch nie das gewünschte Ergebnis. Dies gilt auch für Calculation Views.

Verwendung von Variablen

Die Verwendung von Variablen in SQL-Anweisungen wird nicht durch das ANSI-92-SQL bestimmt. In SAP HANA Cloud implementiert SQLScript das Konzept der Variablen als Erweiterung von ANSI-92 SQL.

Variablen können innerhalb eines Skripts deklariert, zugeordnet und wiederverwendet werden.

Verwendung von Variablen in SQLScript

  • Variable deklarieren

    DECLARE <variable_name> <type> [NOT NULL] [= <value>]

    Beispiel 1: DECLARE a int;

    Beispiel 2: DECLARE b int = 0; (der Wert wird beim Anlegen der Variablen zugewiesen)

  • Weisen Sie eine Variable zu (definieren Sie den Wert einer Variablen).

    <variable_name> = <value> or <expression>

    Beispiel 1: a = 3;

    Beispiel 2: b = select count(*) from baseTable;

  • Variable in einem Ausdruck verwenden

    :<variable_name> (mit einem Doppelpunkt) gibt den aktuellen Wert der Variablen zurück

    Beispiel: b = :a + 5; (weist den Wert von a + 5 bis b zu)

SQLScript-Datentypen

SQLScript fügt auch zusätzliche Datentypen hinzu, um fehlende Funktionen aus Standard-SQL zu beheben, z.B. räumliche Datentypen und Textdatentypen.

Datentypen ANSI-92 und SQLScript

KlassifizierungStandard-ANSI-92-DatentypenSQLScript-spezifische Datentypen
Datum/UhrzeitDATE, TIME, TIMESTAMPSECONDDATE
NumerischDECIMAL INTEGER SMALLINT FLOAT REAL DOUBLETINYINT BIGINT SMALLDECIMAL
ZeichenketteCHAR, NCHAR, VARCHAR, NVARCHARALPHANUM SHORTTEXT
BinärBINARY, VARBINARY 
Großes Objekt BLOB, CLOB, NCLOB, TEXT, BINTEXT
Boolesch BOOLEAN
Räumlich ST_POINT, ST_GEOMETRY

In Calculation Views definierte Eingabeparameter mit SQLScript verarbeiten

Wenn Sie eine SELECT-Anweisung in SQLScript verwenden, um eine Calculation View abzufragen, die Eingabeparameter enthält, verwenden Sie das Schlüsselwort PLACEHOLDER mit dem Namen des Eingabeparameters, der in $$-Symbole verschalt ist, und den Wert, den Sie an den Eingabeparameter übergeben möchten, z.B.:

Eingabeparameter an die Calculation View übergeben

Verwenden Sie das Schlüsselwort PLACEHOLDER, um Eingabeparameter an die Calculation View in einer SELECT-Anweisung zu übergeben:

Code Snippet
1234
SELECT "PRODUCT", sum("TAXED_AMOUNT") FROM "_SYS_BIC"."MyPackage/SalesResults" ('PLACEHOLDER' = ('$$Tax Amount$$', '17.5')) GROUP BY "PRODUCT"
Bezug auf den Eingabeparameter in SQLScript

In SQLScript referenzieren Sie den Eingabeparameter mit einem Doppelpunkt:;

Code Snippet
1
Sales with tax = Sales Revenue * :Tax_Amount

Es ist auch möglich, Ausgabeparameter, die aus einem SQLScript generiert wurden, mithilfe der Parameterzuordnungsfunktion an eine Calculation View zu übergeben.

Looping und Bedingungslogik

Im Allgemeinen wird SQL-Code deklarativ geschrieben. Das bedeutet, dass Sie die Absicht der Aktion angeben und nicht vorgeben, wie die Datenverarbeitungsschritte in einer bestimmten Reihenfolge ausgeführt werden sollen. Wir tun dies, damit der SQL-Optimierer den besten Ausführungsplan basierend auf vielen dynamischen Faktoren zur Laufzeit ermitteln kann.

Manchmal müssen Sie jedoch die Ablauflogik des SQL so steuern, dass die Schritte in einer bestimmten Reihenfolge ausgeführt werden. Dies ist beispielsweise der Fall, wenn Sie einen Schritt nur ausführen müssen, wenn eine bestimmte Bedingung erfüllt ist, oder wenn Sie mehrmals eine Schleife ausführen müssen. In diesen Fällen verwenden Sie die zwingende Logik.

Dies ist (zumeist) nicht in ANSI SQL verfügbar. Daher stellt SAP HANA deklarative Logic Language als Teil von SQLScript bereit, um die Ablaufsteuerung bereitzustellen.

Ein Mangel an zwingender Logiksprache führt häufig dazu, dass der Entwickler die Verarbeitung von Daten in die Anwendungsschicht verlagert. Wenn eine Anwendung auf SAP HANA ausgeführt wird, sollten Sie wirklich so viel Datenverarbeitung wie möglich an die Datenbank senden. Die SAP-HANA-SQLScript-Imperative-Logik ermöglicht dies, sodass weniger Datenbehandlung in den Anwendungsschichten und mehr in der Datenbank erfolgen muss.

Hinweis

Beachten Sie, dass die obligatorische Logik nicht dieselbe Performance wie die deklarative Logik haben kann. Dies liegt daran, dass der SQL-Optimierer nicht frei über die Reihenfolge der Schritte entscheiden kann und darauf achten muss, Ihre Logik zu befolgen, die Optimierungen zerstören kann. Wenn Sie die beste Performance benötigen, versuchen Sie, eine zwingende Logik zu vermeiden.

Bedingungslogik

Die IF-Anweisung
Code Snippet
12345678910
IF <bool-expr1> THEN {then-stmts1} {ELSEIF <bool-expr2> THEN {then-stmts2}} {ELSE {else-stmts3}} END IF
Beispiel für eine IF-Anweisung mit einer ELSE-Klausel.

Die vorherige Abbildung zeigt ein Beispiel für die IF-Anweisung, die aus einem booleschen Ausdruck, :found is NULL, besteht. Wenn der Ausdruck als wahr ausgewertet wird, wird die Anweisung CALL ins_msg_proc('result of count(*) cannot be NULL'); im obligatorischen THEN Block ausgeführt. Die Anweisung IF endet mit END IF. Die restlichen Teile sind optional.

Wenn der Boolesche Ausdruck :found is NULL nicht als wahr ausgewertet wird, wird der ELSE Zweig ausgewertet. In den meisten Fällen beginnt dieser Zweig mit ELSE. Die Anweisung CALL ins_msg_proc('result of count(*) not NULL- as expected'); wird ohne weitere Prüfungen ausgeführt. Nach einer Else-Verzweigung ist kein weiterer ELSE Zweig oder ELSEIF Zweig erlaubt.

Wenn ELSEIF anstelle von ELSE verwendet wird, kann alternativ ein anderer Boolescher Ausdruck ausgewertet werden. Wenn Es als wahr ausgewertet wird, wird die folgende Anweisung ausgeführt. Auf diese Weise können Sie eine beliebige Anzahl von ELSEIF Klauseln hinzufügen.

Mit dieser Anweisung kann die aus vielen Programmiersprachen bekannte Switch-Case-Anweisung simuliert werden.

WHILE- und FOR-Schleifen

Die WHILE-Schleife
Code Snippet
123
WHILE <bool-stmt> DO {stmts} END WHILE
Die WHILE Schleife führt die Anweisung stmts im Hauptteil der Schleife aus, solange der Boolesche Ausdruck am Anfang bool-stmt der Schleife als wahr ausgewertet wird.
Die FOR-Schleife
Code Snippet
123
FOR <loop-var> IN {REVERSE} <start>..<end> DO {stmts} END FOR
Die FOR -Schleife iteriert einen Bereich numerischer Werte – in der Syntax durch Anfang und Ende gekennzeichnet – und bindet den aktuellen Wert in aufsteigender Reihenfolge an eine Variable (loop-var). Die Iteration beginnt mit dem Wert start und wird um eins erhöht, bis die loop-var größer als das Ende ist.

Wenn der Start größer als das Ende ist, wird die Body-Schleife daher nicht ausgewertet. Für jeden Aufzählungswert der Schleifenvariable werden die Anweisungen im Rumpf der Schleife ausgewertet. Das optionale Schlüsselwort REVERSE gibt an, dass der Bereich in absteigender Reihenfolge iteriert werden soll.