Oracle 12.2 Collation

Wenn man den Begriff „Case Insensitive Database“ im „New Feature“ Buch von Oracle 12.2 liest, dann hat man zunächst das Gefühl, dass das vielleicht ein Schritt zurück in die Vergangenheit ist. Denn wir sind uns sicherlich alle einig, dass wir durchaus zwischen Groß- und Kleinschreibung unterscheiden wollen.

In der Realität geht es aber auch gar nicht darum, nur Großbuchstaben in den Tabellen zu speichern, sondern bei der Suche bzw. der Sortierung von Daten auf die Unterscheidung zu verzichten – „Collation“ ist hier das Zauberwort, was Sortierung und Textvergleich bedeutet.

Jeder, der schon einmal eine Anwendung geschrieben hat, kennt das Problem der „richtigen“ Schreibweise und damit der Notwendigkeit, bestimmte Konvertierungen bei Textvergleichen vorzunehmen. Am Einfachsten durch die Funktion „UPPER“ bzw. „LOWER“.

SQL> SELECT persid, vorname, nachname
       FROM mitarbeiter  
      WHERE upper(nachname) = 'MÜLLER'
      ORDER BY nachname, vorname;
    PERSID VORNAME              NACHNAME 
---------- -------------------- --------------------     
    100242 Gerd                 müller     
    100229 Andreas              Müller     
    100483 Carla                Müller     
    101000 Günther              Müller

Das sieht soweit ganz gut aus – bis auf die Sortierung. „Gerd müller“ wird vor „Andreas Müller“ einsortiert, weil der Kleinbuchstabe vor dem Großbuchstaben sortiert wird. Das hätte man vielleicht nicht so erwartet, ist aber keine großartige Neuigkeit. Beheben kann man das z.B. durch die Einstellung der Session auf bestimmte NLS-Variablen, wie diese:

SQL> ALTER SESSION set NLS_SORT='XGERMAN_CI'; 
SQL> SELECT persid, vorname, nachname
       FROM mitarbeiter
      WHERE upper(nachname) = 'MÜLLER
      ORDER BY nachname, vorname;
    PERSID VORNAME              NACHNAME 
---------- -------------------- --------------------
    100229 Andreas              Müller     
    100483 Carla                Müller     
    100242 Gerd                 müller     
    101000 Günther              Müller

Das sieht doch gut aus, oder?

Nicht unbedingt: die Verwendung der Funktion „UPPER“ sowie die Änderung der NLS-Einstellung bewirken, dass Indizes nicht mehr benutzt werden können. Bei der Funktion „UPPER“ leuchtet das noch ein, aber die NLS-EInstellung ist schwer zu erkennen, weil sie ja nicht direkt zum Statement gehört. Daher sei noch einmal darauf hingewiesen, dass es oft nicht ausreichend ist, mit Toad, SQL-Developer oder einem anderen Tool ein Statement mit Explain Plan zu analysieren, man muss auch die Umgebung kennen!

Zurück zum Thema. Die Einstellung von NLS_LANG bewirkt, dass die deutsche Sortierung (xgerman) unabhängig von Groß- und Kleinbuchstaben (CI = Case Insensitive) verwendet werden soll.

Column Level Collation

Diese Einstellung kann man ab Oracle 12.2 einer Tabelle auch direkt mitgeben, wie folgendes Beispiel zeigt:

SQL> ALTER TABLE mitarbeiter MODIFY nachname COLLATE XGERMAN_AI;
SQL> ALTER TABLE mitarbeiter MODIFY vorname COLLATE XGERMAN_AI;
SQL> SELECT persid, vorname, nachname
       FROM mitarbeiter
      WHERE nachname like 'Müller'
      ORDER BY nachname, vorname;
    PERSID VORNAME              NACHNAME 
---------- -------------------- --------------------
    100229 Andreas              Müller     
    100720 Anne                 Muller     
    100025 Blaine               Muller     
    100483 Carla                Müller     
    100594 Elysee               Muller     
    100242 Gerd                 müller     
    101000 Günther              Müller

In diesem Beispiel wurde statt „CI“ der Postfix „AI“ (Accent Insensitive) benutzt, wodurch die Umlaute (Accent) ebenfalls ignoriert wurden. D.h. ob ich jetzt nach „Muller“ oder „Müller“ suche, es werden immer beide Versionen ausgegeben. Natürlich muss die Anwendung das auch tatsächlich wollen!

Was ist eigentlich mit dem schönen deutschen „ß“? Hier kommt jetzt das „X“ von „XGERMAN“ zum Tragen: Während bei „GERMAN“ das „ß“ als eigenständiger Buchstabe hinter dem „s“ einsortiert wird, wird bei „XGERMAN“ ein „ß“ wie ein „ss“ behandelt.

SQL> SELECT persid, vorname, nachname
       FROM mitarbeiter
      WHERE nachname = 'Weiss'
      ORDER BY nachname, vorname;
	 
    PERSID VORNAME              NACHNAME 
---------- -------------------- --------------------
    100645 Randi                Weiß
    100949 Selina               Weiss

Und was ist mit den Indizes?

Für alle Indizes, die vorher schon existiert haben, gilt, dass es sich hierbei um eine Funktion handelt, d.h. die Indizes werden ignoriert. Für Indizes die anschließend angelegt werden, wird die Funktion integriert, d.h. der Index benutzt die zugrundeliegende Funktion. Daher steht der Nutzung von Collatins in diesem Umfeld nichts mehr im Wege.

Neben der direkten Änderung von Tabellenspalten gibt es auch die Möglichkeit, eine Default Collation für eine Tabelle oder ein ganzes Schema zu setzen. Allerdings gilt das nur für neu hinzugefügte Spalten (Tabelle) oder neue Tabellen (Schema), aber das ist vielleicht ein Thema für einen weiteren Blog.

An dieser Stelle möchte ich mich bei Tim Hall bedanken, der mich mit seinem Blog „Column-Level Collation and Case-Insensitive Database in Oracle Database 12c Release 2 (12.2)“ dazu inspiriert hat, mich mit Collations zu beschäftigen – womit dann auch erwiesen ist, dass Engländer etwas für Brauereien übrig haben.

Hinweis

Falls Sie mehr über Collations und weiteren neuen Funktionen von Oracle 12.2 erfahren möchten: nehmen Sie an unserer Schulung „Oracle 12.2 New Features“ im Rahmen der DOAG Konferenz und Ausstellung am 24. November in Nürnberg teil.

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Nach oben scrollen