Der ABAPVARCHARMODE: Leerzeichen und leere Zeichenketten in ABAP und SQLScript

Der ABAPVARCHARMODE: Leerzeichen und leere Zeichenketten in ABAP und SQLScript

Veröffentlicht am 21. April 2021 von

Jörg Brandeis

| ABAP | AMDP | SQLScript |

Die beiden Programmiersprachen ABAP und SQLScript der SAP verhalten, wenn es um die Verarbeitung von Zeichenketten mit Leerzeichen geht, sich in Nuancen unterschiedlich. Das kann zu Fehlern und Verwirrungen führen. Deshalb ist es wichtig, den ABAP VARCHAR Modus bzw. ABAPVARCHARMODE zu verstehen.

Zeichenketten in ABAP mit Textfelder und Textstrings

Leider gibt es hier sogar innerhalb des ABAPs schon die ersten Unterschiede. Die Begriffe Textfelder und Textstrings habe ich der SAP Dokumentation entnommen. Hier der direkte Vergleich

Textfelder, intern ABAP-Typ c

Definition mit

DATA lv_char(10) TYPE c 
                 VALUE 'Brandeis '.
WRITE lv_char && lv_char.

In diesem Datentyp werden Leerzeichen am Ende stets entfernt. Das gilt auch schon für das Textfeldliteral, das mit einem "normalen" Hochkommata notiert wird.

Textstrings, intern ABAP-Typ string

Definition mit

DATA lv_string TYPE string 
               VALUE `Brandeis `.
WRITE lv_string && lv_string.

Beim String bleiben die Leerzeichen erhalten. Aber nur dann, wenn es sich um ein Textstringliteral mit den einfachen Backquotes (=schräge Hochkommata) im Quelltext erfasst wurden. Leider wissen die meisten Menschen noch nicht einmal, wie man diese Backquotes auf einer deutschen Tastatur eingibt. ;-)

Die Konstante SPACE: Eben kein Leerzeichen

blog abap varcharmode

Bei der globalen Konstanten SPACE handelt es sich übrigens um ein Textfeld der Länge 1. Und im ABAP Debugger können wir sehen, das genau ein Leerzeichen drin ist. Aber leider verhält es sich anders. Das merken wir, wenn wir mit dieser Konstanten SPACE eine Verkettung durchführen. Es wird stets ignoriert:

DATA lv_char(10) TYPE c
                 VALUE 'Brandeis '.

WRITE lv_char && SPACE && lv_char.  "Ergibt: BrandeisBrandeis

Das Verhalten von SPACE ist auch deshalb etwas verwirrend, weil es sich als Separator in der CONCATENATE Anweisung wieder anders verhält:

DATA lv_char(10) TYPE c
                 VALUE 'Brandeis'.
DATA lv_concat(20) TYPE c.

CONCATENATE lv_char lv_char INTO lv_concat SEPARATED BY space.

WRITE lv_concat. "Ergibt: Brandeis Brandeis

Hier wird nämlich genau das erwartete Leerzeichen eingefügt!

Zeichenketten mit Leerzeichen in SQLScript

In der SAP HANA Datenbank ist es standardmäßig viel einfacher: Im SQLScript werden Zeichenketten wirklich exakt so gespeichert und verarbeitet, wie sie sind. Leerzeichen bleiben am Ende stehen und es wird nichts automatisch entfernt. Aber natürlich gibt es hier eine Ausnahme, die fast schon die Regel ist: der ABAP VARCHAR Modus1. Dieser wird verwendet, wenn sich die SAP HANA als Datenbank unter einem ABAP System wie z.B. einem S/4HANA oder BW/4HANA befindet, um kompatibel mit dem SPACE des ABAP zu sein.

Warum ein extra Modus?

Leere bzw. initiale Zeichenketten werden von ABAP als SPACE, also tatsächlich ein Leerzeichen in die Datenbank geschickt. In ABAP funktioniert deshalb auch das SPACE als Vergleichswert in WHERE Bedingungen. Das bedeutet, das eine Selektion in SQLScript eigentlich jeweils mit einem Leerzeichen stattfinden müsste. Mit dem ABAP VARCHAR Modus wird der HANA mitgeteilt: Mache keinen Unterschied zwischen einem einzelnen Leerzeichenliteral und einer leeren Zeichenkette. Beide werden auf die leere Zeichenkette abgebildet. Das macht die Selektion in SQLScript leichter.

Damit ist das Selektionsproblem gelöst, aber ein neues Problem ist entstanden: Wenn wir mal einfach so ein einzelnes Leerzeichen brauchen, können wir es nicht mehr als Literal ' ' angeben. Denn daraus wird automatisch ein ''. Wie bei Textfeldern im ABAP haben wir also ein Problem, wenn wir beispielsweise zwei Wörter mit einem Leerzeichen trennen möchten. Statt einem Literal mit einer Leerzeichen müssen wir statt dessen den Funktionsaufruf CHAR(32) bemühen, uns ein Leerzeichen zu produzieren:

SELECT 'Peter' || ' ' || 'Mueller' FROM DUMMY;      --Funktioniert nicht so wie gewünscht

SELECT 'Peter' || char(32) || 'Mueller' FROM DUMMY; --Trennt mit einem Leerzeichen

Der Sessionvariable ABAPVARCHARMODE

Wir können in unsere Quellcode direkt herausfinden, ob der ABAP VARCHAR Modus aktiv ist oder nicht. Diese Information steht in der Sessionvariablen ABAPVARCHARMODE. Wenn darien der Wert TRUE steht, verhält sich die Verarbeitung in SQLScript wie oben beschrieben. Wir können diesen Modus zu Testzwecken auch selber setzen. Allerdings ist das gefährlich. Denn als Sessionparameter gilt diese Einstellung für die ganze Datenbanksession. Hier sollten wir bei AMDPs den Standardwert nicht verändern.

Zum Ausprobieren in der SQL-Konsole können Sie aber diesen Code hier verwenden. Er zeigt schön, wie sich das Verhalten bei der Abfrage verändert:

SET 'ABAPVARCHARMODE' = 'FALSE';
SELECT 'Peter' || ' ' || 'Mueller' FROM DUMMY;
SET 'ABAPVARCHARMODE' = 'TRUE';
SELECT 'Peter' || ' ' || 'Mueller' FROM DUMMY;

Zusammenfassung

Leerzeichen am Ende einer Zeichenkette werden in ABAP normalerweise entfernt, in SQLScript nicht. Bei den leeren Zeichenketten bzw. Zeichenketten und Literalen, die aus genau einem Leerzeichen bestehen, gibt es in SQLScript Probleme, falls ein ABAP System involviert ist. Denn hier findet eine Abbildung von einem Leerzeichen auf die Leere Zeichenkette statt. Mit dem Funktionsaufruf CHAR(32) kann man sich aber gut behelfen.

1 Siehe SAP Hinweis 2262114 - One Space Handling for ABAP in SAP HANA