Eingebettete (oder anonyme) Funktionen in SQLScript
Veröffentlicht am 8. November 2019 von | News | SQLScript |
Mit SAP HANA 2.0 SPS04 ist mit den eingebetteten Funktionen ein weiteres Feature zur Sprache SQLScript hinzugekommen. Diese ermöglichen die Verwendung von imperativem SQLScript Code innerhalb einer SELECT Abfrage. Diese Funktionen werden nur für exakt diese eine Abfrage erstellt und nur dort ausgeführt. Da diese Funktionen keinen Namen bekommen, werden sie auch als Anonyme Funktionen bezeichnet.
Im folgenden Beispiel wird die Abfrage mit einer eingebetteten Funktion innerhalb einer Prozedur aufgerufen.
- Die eingebettete Funktion beginnt mit Zeile 11 und endet in Zeile 37. Sie enthält imperatives Coding, womit die ganze Prozedur imperativ ist.
- Der Parameter
IV_MAX
der Prozedur wird in Zeile 11 an den ParameterIV_A
der Funktion weitergegeben. Dieser wird dann in Zeile 24 als Obergrenze für die FOR-Schleife verwendet wird. Ein direkter Zugriff aufIV_MAX
innerhalb der Funktion ist nicht möglich. - Die WHERE-Bedingung in Zeile 38 verdeutlicht nochmals, dass es sich um eine Abfrage handelt
- Mit der CALL Anweisung in Zeile 41 können Sie die Prozedur testen.
CREATE PROCEDURE test_anonymous_function
(IN iv_max INT,
OUT ot_result TABLE(number INTEGER,
letter VARCHAR ) )
AS BEGIN
ot_result =
SELECT number,
letter
FROM
SQL FUNCTION (IN iv_a INT => :iv_max)
RETURNS TABLE (number INT,
letter VARCHAR(1))
BEGIN
DECLARE lv_cnt INT;
DECLARE lv_chars VARCHAR(30)
DEFAULT 'ABCDEFGHIJKLMNOP';
lt_result = SELECT 0 AS number,
' ' AS letter
FROM dummy
WHERE dummy <> 'X';
FOR lv_cnt IN 1..:iv_a DO
lt_result = SELECT * FROM :lt_result
UNION
SELECT lv_cnt AS number,
SUBSTRING(:lv_chars,
:lv_cnt,
1) AS letter
FROM dummy;
END FOR;
RETURN SELECT * FROM :lt_result;
END
WHERE MOD(number, 2) = 0 ;
END;
CALL test_anonymous_function(13, ?);
Von der Verwendung von eingebetteten Funktionen rate ich grundsätzlich ab, da bereits einfache Funktionen die Lesbarkeit des Codes erheblich verschlechtern. Dies konnten Sie auch deutlich an dem gezeigten Beispiel sehen.
Als Alternative bietet sich die Anlage einer separaten UDF-Funktion an oder die Zerlegung der Abfrage in zwei Schritte:
- Erzeugung einer Tabellenvariablen mit dem imperativen Code
- Abfrage auf diese Tabellenvariable
Durch diese Zerlegung lässt sich der Code besser lesen. Und es ist im Debugger möglich, die Zwischenergebnisse zu betrachten. Manchmal sind diese Alternativen aber aus technischen Gründen nicht möglich. Dann erlauben uns die eingebetteten Funktionen die Nutzung von imperativem Code direkt in einer Abfrage.