Oracle varchar2 Felder vergleichen

9 12 2011

Vergleicht man im PL/SQL varchar2 Variablen, so sind gleiche Inhalte manchmal doch nicht wirklich gleich. Zur Verdeutlichung soll dieses Beispiel herhalten:

declare
v_var1 varchar(20);
v_var2 varchar(30);
v_var3 varchar(30);

begin
v_var1 := 'Test';
v_var2 := 'Test';
v_var3 := 'Test   ';

if v_var1 = v_var2 then dbms_output.put_line('Eins ist ok'); end if;
if v_var1 = v_var3 then dbms_output.put_line('Zwei ist ok'); end if;
if v_var2 = v_var3 then dbms_output.put_line('Drei ist ok'); end if;
end;
/

Was würde man nun vermuten, kommt als Ausgabe heraus? Im Grunde sind die Texte identisch. Allerdings erhalten wir nur die erste Zeile zurück:
Eins ist ok
Was sagt uns das? Ob die Variable mit einer Länge von 20 oder 30 Zeichen definiert ist, ist egal. So weit so gut, nichts anderes hätten wir erwartet. Warum aber ist die Variable 3 nicht identisch zu den anderen Beiden? Dazu beachte man die Leerzeichen am Ende des Strings. Diese werden im Vergleich also mit berücksichtigt.

Leuchtet ein? Vielleicht, doch nutzt man Character-Felder, sieht die Sache gleich wieder anders aus. Ändern wir also die Variablendefinition zu char, erhalten wir ein anderes Ergebnis:

v_var1 char(20);
v_var2 char(30);
v_var3 char(30);

Ergibt als Ausgabe:
Eins ist ok
Zwei ist ok
Drei ist ok

Warum ist das so? Dazu muss man wissen, dass laut Definition des SQL Standards zwei zu vergleichende Strings immer gleich lang sein müssen. Ist ein String kürzer, wird dieser zur Länge des zu vergleichenden Strings mit Blanks aufgefüllt.

v_var2 := 'Test '; -- Wird mit Blanks aufgefüllt
v_var3 := 'Test ';

Somit erkennen wir, die beiden Variablen sind tatsächlich identisch. Das funktioniert natürlich nur mit Blanks am Ende.

Da der varchar2 Typ aber genau dem Zweck dient, immer nur die exakte Länge eines Strings zu speichern, wird hier nicht aufgefüllt, sondern beide Strings werden genau mit der Länge verglichen, die sie auch tatsächlich besitzen. Will man Strings unabhängig nachgelagerter Leerzeichen vergleichen, sollten die Variablen also als pure Character definiert sein.

Doch was, wenn in dem eigenen Skript varchar2 Felder aus welchem Grund auch immer praktischer sind? Dann müssen wir darauf nicht verzichten. Mittels der trim Funktion können wir beim Vergleich dafür sorgen, dass diese Zeichen entfernt werden. Wir erweitern den Vergleich aus dem ersten Beispiel ein wenig…

if trim(v_var1) = trim(v_var2) then dbms_output.put_line('Eins ist ok'); end if;
if trim(v_var1) = trim(v_var3) then dbms_output.put_line('Zwei ist ok'); end if;
if trim(v_var2) = trim(v_var3) then dbms_output.put_line('Drei ist ok'); end if;

…und schon haben wir auch mit varchar2 Variablen das gewünschte Ergebnis:
Eins ist ok
Zwei ist ok
Drei ist ok

Grundsätzlich hätte hier auch ein rtrim gereicht, doch mit trim gehen wir zudem noch sicher, dass selbst führende Leerzeichen nicht stören.

Advertisements

Aktionen

Information

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s




%d Bloggern gefällt das: