benutzerdefinierte Ordnung

Die üblichen Vergleichsoperatoren wie =, <, >, <>, <=, => LIKE, BETWEEN etc. lassen sich nur auf Basisdatentypen? anwenden, nicht aber auf benutzerdefinierte-Datentypen. Daher ist es notwendig, entweder die Typen der beteiligten Operanden mittels CAST-Funktionen auf Basisdatentypen zurückzuführen, so dass die üblichen Operatoren zum Einsatz kommen können, oder aber die Programmierung von Funktionen, die den Vergleich auf der Basis der benuzterdefinierten Datentypen durchführen, den sogenannten benutzerdefinierten Ordnungen. Da der dafür erforderliche CREATE ORDERING-Befehl nur die sechs Vergleichsprädikate =, <, >, <>, <=, => kennt, lassen sich Vergleiche mit LIKE und BETWEEN und anderen Spezialoperatoren nur über eine Rückführung der benutzerdefinierten Datentypen auf Basisdatentypen mittels CAST realisieren.

Wie die Syntax des CREATE ORDERING-Befehls weiter unten zeigt, verfügt eine Ordnungsfunktion über verschiedene Eigenschaften:

  • Ordnungsform:
    • EQUALS ONLY für =, <>
    • ORDER FULL für =, <, >, <>, <=, =>
  • Ordnungskategorie:
    • RELATIVE WITH FUNCTION: Die Funktion vergleicht die Werte der beiden Eingabeparameter mit benutzerdefinierten Datentypen und gibt einen Integerwert zurück, der die relative Ordnung spezifiziert, z.B. 1 für richtige Ordnung, -1 für falsche Ordnung. Da Integer als Rückgabewert gegeben ist, sind beliebig komplexe Ordnungen möglich.
    • MAP WITH FUNCTION: Die Ordnung wird definiert, indem die Funktion den Wert eines benutzerdefinierten Datentyps auf ein Wert eines Basisdatentyps abbildet.
    • STATE: Es wird eine boolesche Funktion generiert, die TRUE liefert, wenn die beiden zu vergleichenden strukturierten Werte paarweise in allen Attributen übereinstimmen, woraus eine Beschränkung bei der Ordnungsform auf EQUALS ONLY resultiert.

Die beiden Ordnungskategorien RELATIVE WITH FUNCTION und MAP WITH FUNCTION erfordern, dass zuvor mittels der Anweisung CREATE FUNCTION eine Funktion programmiert wurde, die die Vergleiche, Berechnungen, Tranformationen etc. realisiert. Anschließend wird diese Funktion mit der CREATE ORDERING-Anweisung als Ordnungsfunktion deklariert.

SQL-/Oracle-Syntax der ORDERING-Funktion:

    <CREATE ORDERING Anweisung> ::=
CREATE ORDERING FOR Typname
{ EQUALS ONLY | ORDER FULL } { RELATIVE WITH FUNCTION Funktionsname(Typname, Typname) | MAP WITH FUNCTION Funktionsname(Typname) | STATE [Funktionsname]}

Gelöscht wird eine benutzerdefnierte Ordnung mittels DROP ORDERING-Anweisung.

Beispiel:

   -- Deklaration eines benutzerdefinierten Datentyps
   CREATE TYPE NameTyp       AS (Titel   VARCHAR(10), Vorname   VARCHAR(50), Nachname VARCHAR(30)) NOT FINAL; 
   DECLARE     Mitarbeiter       NameTyp;
   DECLARE     Kunde             NameTyp;

   -- Ordnungsoption STATE
   CREATE ORDERING FOR NameTyp EQUALS ONLY BY STATE namensgleich;   

   IF namensgleich(Mitarbeiter, Kunde) THEN   -- Es wird verglichen, ob die Titel, Vornamen, Nachnamen von Kunde und Mitarbeiter jeweils gleich sind.      

   -- ------------------------------------------------------
   -- analoges Beispiel mit Ordnungsoption RELATIVE WITH FUNCTION 
   CREATE FUNCTION namensgleiche_func(Person1 IN NameTyp, Person2 IN NameTyp)
   RETURNS INTEGER
   BEGIN
      IF Person1.Titel    = Person2.Titel     AND 
         Person1.Vorname  = Person2.Vorname   AND 
         Person1.Nachname = Person2.Nachname  AND 
      THEN RETURN 1;
      ELSE IF Person1.Nachname > Person2.Nachname  THEN RETURN -1 
      ELSE IF Person1.Nachname < Person2.Nachname  THEN RETURN -2 
      ELSE IF Person1.Vorame   > Person2.Vorname   THEN RETURN -3 
      ELSE IF Person1.Vorame   < Person2.Vorname   THEN RETURN -4 
      ELSE IF Person1.Titel    > Person2.Titel     THEN RETURN -5 
      ELSE IF Person1.Titel    < Person2.Titel     THEN RETURN -6 
      END IF; 
   END; 

   -- Ordnungsoption RELATIVE WITH FUNCTION
   CREATE ORDERING FOR NameTyp EQUALS ONLY BY RELATIVE WITH FUNCTION namensgleiche_func(NameTyp, NameTyp);   
   DECLARE Vergleichsergebnis     INTEGER;
   SET Vergleichsergebnis = namensgleiche_func(Mitarbeiter, Kunde);
   IF  Vergleichsergebnis = 1 THEN ...
   ELSE IF  Vergleichsergebnis = -1 THEN ...
   ELSE IF  Vergleichsergebnis = -2 THEN ...
   ELSE IF  Vergleichsergebnis = -3 THEN ...
   ...
   END IF; 


Quellen:

  • ANSI/ISO/IEC 9075-1:2003. Part 1 "SQL/Framework", ISO International Organization for Standardization / ANSI American National Standards Institute, September 2003
  • ANSI/ISO/IEC 9075-2:2003. Part 2 "SQL/Foundation", ISO International Organization for Standardization / ANSI American National Standards Institute, Dezember 2003
  • Türker, Can, Saake, Gunter: "Objektrelationale Datenbanken", dpunkt-verlag, Heidelberg, 2006, ISBN 3-89864-190-2

Kategorien: Objektrelationale DB, B, O