Objekt-relationale und erweiterbare Datenbanksysteme Erweiterbarkeit SQL:1999 Objekt-relationale Modellierung Konzepte objekt-relationaler Datenbanken Große Objekte (Large OBjects, LOBs) Datentypen, die es erlauben, sehr große Attributwerte, bspw. Multimedia-Daten, zu speichern. Typische Größe: Gigabyte-Bereich. Mengenwertige Attribute Einem Tupel (Objekt) wird in einem Attribut eine Menge von Werten zugeordnet Damit ist es beispielsweise möglich, der Relation Studenten ein mengenwertiges Attribut ProgrSprachenKenntnisse zuzuordnen. Schachtelung / Entschachtelung in der Anfragesprache 2 Konzepte objekt-relationaler Datenbanken Geschachtelte Relationen (NF2) Geschachtelte Relationen gehen einen Schritt weiter als mengenwertige Attributen und erlauben Attribute, die selbst wiederum Relationen sind. Beispiel: Relation Studenten enthält Attribut absolviertePrüfungen, unter dem die Menge von PrüfungenTupeln gespeichert ist. Jedes Tupel dieser geschachtelten Relation besteht selbst wieder aus Attributen, wie z.B. Note und Prüfer. Benutzer-definierte Typen Objekt-relationale Datenbanksysteme unterstützen die Definition von anwendungsspezifischen Typen – oft userdefined types (UDTs) genannt. Unterscheidet zwischen wert-basierten (Attribute Type) und Objekt-Typen (Row Type). 3 Konzepte objekt-relationaler Datenbanken Referenzen Attribute können direkte Referenzen auf Tupel/Objekte (derselben oder anderer Relationen) als Wert haben. Zwang zur Nutzung von Fremdschlüsseln zur Realisierung von Beziehungen aufgehoben. Insbesondere kann ein Attribut eine Menge von Referenzen als Wert haben, so dass man auch N:M-Beziehungen ohne separate Beziehungsrelation repräsentieren kann Beispiel: Studenten.hört ist eine Menge von Referenzen auf Vorlesungen Objektidentität Referenzen setzen natürlich voraus, dass man Objekte (Tupel) anhand einer unveränderlichen Objektidentität eindeutig identifizieren kann Pfadausdrücke Referenzattribute führen unweigerlich zur Notwendigkeit, Pfadausdrücke in der Anfragesprache zu unterstützen (implizite (Self-)Joins). 4 Konzepte objekt-relationaler Datenbanken Vererbung Komplex strukturierten Typen können Eigenschaften von einem Obertyp erben. Weiterhin kann man Relationen als Unterrelation einer Oberrelation definieren. Alle Tupel der Unter-Relation sind dann implizit auch in der Ober-Relation enthalten. Damit wird das Konzept der Generalisierung/Spezialisierung realisiert. Operationen Können Objekttypen zugeordnet werden Einfache Operationen können direkt in SQL implementiert werden Komplexere werden in einer Host-Sprache „extern“ realisiert Java, C, PLSQL (Oracle-spezifisch), C++, etc. 5 Standardisierung in SQL:1999 SQL2 bzw. SQL:1992 Derzeit realisierter Standard der kommerziellen relationalen Datenbanksysteme Vorsicht: verschiedene Stufen der Einhaltung Entry level ist die schwächste Stufe SQL:1999 Objekt-relationale Erweiterungen Trigger Stored Procedures Erweiterte Anfragesprache Viele Systeme haben schon ihre eigene proprietäre Syntax (und Semantik) realisiert 6 Große Objekte: Large Objects CLOB In einem Character Large OBject werden lange Texte gespeichert. Der Vorteil gegenüber entsprechend langen varchar(...) Datentypen liegt in der verbesserten Leistungsfähigkeit, da die Datenbanksysteme für den Zugriff vom Anwendungsprogramm auf die LOBs spezielle Verfahren (sogenannte Locator, oft Referenzen in das Dateisystem des OS) anbieten. BLOB In den Binary Large Objects speichert man solche Anwendungsdaten, die vom Datenbanksystem nicht interpretiert sondern nur gespeichert bzw. archiviert werden sollen. NCLOB CLOBs sind auf Texte mit 1-Byte Character-Daten beschränkt. Für die Speicherung von Texten mit Sonderzeichen, z.B. Unicode-Texten müssen deshalb sogenannte National Character Large Objects (NCLOBs) verwendet werden In DB2 heißt dieser Datentyp (anders als im SSQL:1999 Standard) DBCLOB -- als Abkürzung für Double Byte Character Large OBject 7 Beispiel-Anwendung von LOBs CREATE TABLE Professoren ( PersNr INTEGER PRIMARY KEY, Name VARCHAR(30) NOT NULL, Rang CHARACTER(2) CHECK (Rang IN ('C2', 'C3', 'C4')), Raum INTEGER UNIQUE, Passfoto BLOB(2M), Lebenslauf CLOB(75K) ); • Separater Speicherort für LOBs (hier: Oracle-Syntax): LOB (Lebenslauf) STORE AS ( TABLESPACE Lebensläufe STORAGE (INITIAL 50M NEXT 50M) ); 8 Einfache benutzer-definierte Typen: Distinct Types SQL DBMS unterstützen bereits eine Vielzahl atomarer Datentypen (INTEGER, CHAR, DECIMAL, NUMERIC, …) Viele Typen in Anwendungen sind jedoch oft spezifischer Die Modellierung mit vordefinierten Typen kann problematisch sein: SELECT * FROM Studenten s WHERE s.Stundenlohn > s.VordiplomNote; Vergleich bzgl. des Typsystems zulässig (Attribute Stundenlohn und VordiplomNote implementiert durch DECIMAL(3,2)). 9 Einfache benutzer-definierte Typen: Distinct Types Erzeugung eines benutzer-definierten Typs, der sich 1:1 auf vordefinierten SQL-Typ abbilden läßt: CREATE DISTINCT TYPE NotenTyp AS DECIMAL(3,2) WITH COMPARISONS; Ein Vergleich von Werten der Typen DECIMAL(3,2) und NotenTyp wird durch das Typsystem verboten (distinct type). Fehlt noch: Zuordnung von Operationen zu NotenTyp 10 Einfache benutzer-definierte Typen: Distinct Types CREATE DISTINCT TYPE NotenTyp AS DECIMAL (3,2) WITH COMPARISONS; CREATE FUNCTION NotenDurchschnitt(NotenTyp) RETURNS NotenTyp SOURCE AVG(DECIMAL()); CREATE TABLE Pruefen ( MatrNr INT, VorlNr INT, PersNr INT, Note NotenTyp); Explizites Casting INSERT INTO Pruefen VALUES (28106,5001,2126,NotenTyp(1.00)); INSERT INTO Pruefen VALUES (25403,5041,2125,NotenTyp(2.00)); INSERT INTO Pruefen VALUES (27550,4630,2137,NotenTyp(2.00)); SELECT NotenDurchschnitt(Note) AS UniSchnitt FROM Pruefen; 11 Konvertierungen zwischen Noten-Typen CREATE DISTINCT TYPE US_NotenTyp AS DECIMAL (3,2) WITH COMPARISONS; CREATE FUNCTION USnachD_SQL(us US_NotenTyp) RETURNS NotenTyp RETURN (CASE WHEN DECIMAL(us) < 1.0 THEN NotenTyp(5.0) WHEN DECIMAL(us) < 1.5 THEN NotenTyp(4.0) WHEN DECIMAL(us) < 2.5 THEN NotenTyp(3.0) WHEN DECIMAL(us) < 3.5 THEN NotenTyp(2.0) ELSE NotenTyp(1.0) END); CREATE TABLE TransferVonAmerika ( MatrNr INT, VorlNr INT, Universitaet VARCHAR(30), Note US_NotenTyp); 12 Anwendung der Konvertierung in einer Anfrage INSERT INTO TransferVonAmerika VALUES (28106, 5041, "Univ. Southern California", US_NotenTyp(4.00)); SELECT MatrNr, NotenDurchschnitt(Note) FROM ( (SELECT Note, MatrNr FROM Pruefen) UNION (SELECT USnachD_SQL(Note) AS Note, MatrNr FROM TransferVonAmerika) ) AS AllePruefungen GROUP BY MatrNr 13 Table Functions: Import externer Datenquellen als Tabellen Erweiterbare SQL-Systeme (hier: DB2) bieten zusätzlich die Möglichkeit, externe Quellen (etwa Files, Ausgaben anderer Prozesse), in Form von relationalen Tabellen zu importieren. Eine derartige benutzer-definierte Funktion (table function) liefert damit ganze Tabellen (nicht einzelne atomare Attributwerte) an das SQL-System. Das Ergebnis eines table function-Aufrufes kann in SQLAnfragen wie eine Relation (oder View) genutzt werden. Häufige Bezeichnung: wrapper Beispiel externe Quelle: ASCII-File (CSV: comma separated values) 1, foo <NL> 2, bar <NL> 14 Table Functions: Import externer Datenquellen als Tabellen Ziel: Import des Ergebnisses einer Web-Anfrage (Suchmaschine) als relationale Tabelle. Table function: Biographien: STRING -> {[ URL: VARCHAR(40), Sprache: VARCHAR(20), Ranking: DECIMAL ]} SELECT bio.URL, bio.Ranking FROM TABLE(Biographien('Sokrates')) AS bio WHERE bio.Sprache = 'Englisch' ORDER BY bio.Ranking; SELECT FROM WHERE ORDER BY prof.Name, bio.URL, bio.Ranking Professoren AS prof, TABLE(Biographien(prof.Name)) AS bio bio.Sprache = 'German' prof.Name, bio.Ranking; 15 Realisierung (Deklaration) einer Table Function CREATE FUNCTION Biographien(VARCHAR(20)) RETURNS TABLE (URL VARCHAR(40), Sprache VARCHAR(20), Ranking DECIMAL) EXTERNAL NAME '/usr/..../Wrappers/Biographien.o' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL NOT DETERMINISTIC NO EXTERNAL ACTION FENCED NO SCRATCHPAD NO FINAL CALL CARDINALITY 20; 16 Table Functions: Call Types Die externe Routine wird vom DBMS mit einem Status-Flag aufgerufen, das anzeigt, wie die Auswertung der umgebenden SQL-Query voranschreitet: SQLUDF_FIRST SQLUDF_OPEN SQLUDF_FETCH SQLUDF_CLOSE SQLUDF_FINAL (Routine kann "letztes Tupel" signalisieren) Dies simuliert das klassische Iterator-basierte Auswertungsprinzip, das die SQL-Engine auch auf ihre internen Operatoren anwendet 17 Uni-Schema voraussetzen Nachfolger Vorgänger MatrNr N Name Semester Studenten N hören M M Note Name Fachgebiet 1 Assistenten N arbeitenFür N SWS Titel lesen prüfen PersNr M Vorlesungen N VorlNr 1 1 Professoren PersNr Name Rang Raum 18 +Hörer 1 +Nachfolger 1..* hören * +Prüfling * Prüfungen +Note : Decimal +Datum : Date +verschieben() Assistenten +Fachgebiet : String +Gehalt() : short Vorlesungen +VorlNr : int +Titel : String +SWS : int +AnzHörer() : int +DurchfallQuote() : float * 1 * 1 +Boss * arbeitenFür 1 voraussetzen * * * +Prüfungsstoff gelesenVon Studenten +MatrNr : int +Name : String +Semester : int +Notenschnitt() : float +SummeWochenstunden() : short +Prüfer Professoren +Rang : String +Notenschnitt() : float +Gehalt() : short +Lehrstundenzahl() : short 1 +Dozent Angestellte +PersNr : int +Name : String +Gehalt() : short +Steuern() : short 19 Benutzer-definierte Objekt-Typen Ganz analog zum Objektmodell in OODBMS, akzeptieren SQL:1999 DBMS die Definition strukturierter Objekte, in denen Daten (Attribute) und Verhalten (Methoden, hier: member functions) gemeinsam deklariert und manipuliert werden CREATE [ OR REPLACE ] TYPE OT AS ( … ); Weiterhin können Vererbungsbeziehungen (Spezialisierung, Generalisierung) zwischen Objekt-Typen realisiert werden Das ORDBMS verwaltet Objektidentiät und implementiert Referenzen (REF OT) 20 Objekt-Typ-Definitionen (Oracle) Hier: implementiere die Vererbungsbeziehung Professoren is-a Angestellte noch "manuell" CREATE OR REPLACE TYPE ProfessorenTyp AS ( PersNr NUMBER, Name VARCHAR(20), Rang CHAR(2), Raum NUMBER, MEMBER FUNCTION Notenschnitt RETURN NUMBER, MEMBER FUNCTION Gehalt RETURN NUMBER ) CREATE OR REPLACE TYPE AssistentenTyp AS ( PersNr NUMBER, Name VARCHAR(20), Fachgebiet VARCHAR(20), Boss REF ProfessorenTyp, MEMBER FUNCTION Gehalt RETURN NUMBER ) 21 Implementierung der Operationen eines Objekt-Typs CREATE OR REPLACE TYPE BODY ProfessorenTyp AS MEMBER FUNCTION Notenschnitt RETURN NUMBER IS BEGIN /* Finde alle Prüfungen des/r Profs und ermittle den Durchschnitt */ END; MEMBER FUNCTION Gehalt RETURN NUMBER IS BEGIN RETURN 1000.0; /* Einheitsgehalt für alle */ END; 22 Tabellen für Objekt-Typen (Extents) definiert implizit die Spalten der Tabelle CREATE TABLE ProfessorenTab OF ProfessorenTyp (PersNr PRIMARY KEY) ; INSERT INTO ProfessorenTab INSERT INTO ProfessorenTab INSERT INTO ProfessorenTab INSERT INTO ProfessorenTab INSERT INTO ProfessorenTab INSERT INTO ProfessorenTab INSERT INTO ProfessorenTab VALUES (2125, 'Sokrates' , 'C4', 226 ); VALUES (2126, 'Russel' , 'C4', 232 ); VALUES (2127, 'Kopernikus', 'C3', 310 ); VALUES (2133, 'Popper' , 'C3', 52 ); VALUES (2134, 'Augustinus' , 'C3', 309 ); VALUES (2136, 'Curie' , 'C4', 36 ); VALUES (2137, 'Kant' , 'C4', 7 ); 23 Objekt-Typ-Definitionen und eingebettete Referenzen (1:n, m:n) Implementiere die Menge der Voraussetzungen einer Vorlesung durch eine eingebettete Tabelle, die Referenzen auf Vorlesungen enthält: CREATE OR REPLACE TYPE VorlRefListenTyp AS TABLE OF REF (VorlesungenTyp); / CREATE OR REPLACE TYPE VorlesungenTyp AS ( VorlNr NUMBER, Titel VARCHAR(20), SWS NUMBER, gelesenVon REF ProfessorenTyp, Voraussetzungen VorlRefListenTyp, MEMBER FUNCTION DurchfallQuote RETURN NUMBER, MEMBER FUNCTION AnzHoerer RETURN NUMBER ) 24 Tabellarische Darstellung eines VorlesungenTyp-Objekts VorlNr Titel SWS 5049 Mäeutik 2 gelesenVon Voraussetzungen ... ... ... ... ... Referenz auf ProfessorenTyp-Objekt R Volre eferenze n sung enT y a uf p-Ob jekte 25 Anlegen der Tabellen(!) für Objekte des Typs VorlesungenTyp Die Voraussetzungen aller Vorlesungen werden in einer geschachtelten Tabelle (VorgaengerTab) aufbewahrt: CREATE TABLE VorlesungenTab OF VorlesungenTyp NESTED TABLE Voraussetzungen STORE AS VorgaengerTab; Das ORDBMS verwaltet dabei automatisch die Beziehung von Tupeln aus VorgaengerTab zum übergeordneten VorlesungenTabTupel (s. nächste Folie). Clustering Achtung: Hier vermischen sich konzeptuelle und interne Ebene. 26 Tabelle VorlesungenTab und geschachtelte Tabelle VorgaengerTab VorlesungenTab VorlNr 5049 Titel Mäeutik SWS 2 VorgaengerTab Referenzen auf VorlesungenTyp-Objekte gelesenVon Voraussetzungen ... ... ... Referenz auf ProfessorenTyp-Objekt ... ... 5041 Ethik 4 ... ... ... 5216 Bioethik 2 ... ... ... ... 27 Einfügen von VorlesungenTyp-Objekten INSERT INTO VorlesungenTab SELECT 5041, 'Ethik', 4, REF(p), VorlesungsListenTyp() FROM ProfessorenTab p WHERE Name = 'Sokrates'; Lokalisiere Professoren-Objekt mittels wert-basiertem Schlüssel INSERT INTO VorlesungenTab SELECT 5216, 'Bioethik', 2, REF(p), VorlRefListenTyp() FROM ProfessorenTab p Leere geschachtelte WHERE Name = 'Russel'; Relation INSERT INTO TABLE (SELECT nachf.Voraussetzungen FROM VorlesungenTab nachf WHERE nachf.Titel = 'Bioethik') SELECT REF(vorg) FROM VorlesungenTab vorg WHERE vorg.Titel = 'Ethik'; 28 Objekt-Typen und tatsächlich eingebettete Objekte (<> Referenzen!) Zur Modellierung von Aggregationen (sog. Kompositionen) mit exklusiver 1:N-Zuordnung von Subobjekten existenzabhängiger Zuordnung (Schachtelung schwacher Entities im übergeordneten Entity) Studenten +MatrNr : int +Name : String +Semester : int +Notenschnitt() : float +SummeWochenstunden() : short +Prüfling 1 absolviert * Prüfungen +Note : Decimal +Datum : Date +verschieben() * ... 1 +Prüfer * +Prüfungsstoff 1 ...29 Geschachtelte Objekt-Typen führen zu geschachtelten Relationen CREATE OR REPLACE TYPE PruefungenTyp AS ( Inhalt REF VorlesungenTyp, Pruefer REF ProfessorenTyp, Note DECIMAL(3,2), Datum DATE, MEMBER FUNCTION verschieben(neuerTermin DATE) RETURN DATE); CREATE OR REPLACE TYPE PruefungsListenTyp AS TABLE OF PruefungenTyp; CREATE OR REPLACE TYPE StudentenTyp AS ( MatrNr NUMBER, kein REF( )! Name VARCHAR(20), Semester NUMBER, hört VorlRefListenTyp, absolviertePrüfungen PruefungsListenTyp, MEMBER FUNCTION Notenschnitt RETURN NUMBER, MEMBER FUNCTION SummeWochenstunden RETURN NUMBER); 30 Anlegen und Bevölkern der Tabelle für StudentenTyp CREATE TABLE StudentenTab OF StudentenTyp (MatrNr PRIMARY KEY) NESTED TABLE hört STORE AS BelegungsTab NESTED TABLE absolviertePrüfungen STORE AS ExamensTab; INSERT INTO StudentenTab VALUES (24002, 'Xenokrates', 18, VorlRefListenTyp(), PruefungsListenTyp()); INSERT INTO StudentenTab VALUES (29120, 'Theophrastos', 2, VorlRefListenTyp( ), PruefungsListenTyp()); INSERT INTO TABLE (SELECT s.hört FROM StudentenTab s WHERE s.MatrNr = 29120) SELECT REF(v) FROM VorlesungenTab v WHERE v.gelesenVon->Name = 'Sokrates'; 31 Einfügen in geschachtelte Tabellen (Zuordnung Prüfungen/Studenten) INSERT INTO TABLE (SELECT s.absolviertePrüfungen FROM StudentenTab s WHERE s.MatrNr = 29120) VALUES ((SELECT REF(v) FROM VorlesungenTab v WHERE v.Titel='Maeeutik'), (SELECT REF(p) FROM ProfessorenTab p WHERE p.Name='Sokrates'), 1.3, SYSDATE); INSERT INTO TABLE (SELECT s.absolviertePrüfungen FROM StudentenTab s WHERE s.MatrNr = 29120) VALUES ((SELECT REF(v) FROM VorlesungenTab v WHERE v.Titel='Ethik'), (SELECT REF(p) FROM ProfessorenTab p WHERE p.Name='Sokrates'), 1.7, SYSDATE); 32 Darstellung der StudentenTab ( : Referenzen ) StudentenTab MatrNr 24002 MatrNr 29120 MatrNr 28106 Name Xenokrates Name Theophrastos Name Carnap Semester 18 hört Inhalt Semester 2 hört Semester 3 hört Inhalt Inhalt absolviertePrüfungen Prüfer Note Datum ... ... ... ... ... ... absolviertePrüfungen Prüfer Note 1.3 1.7 absolviertePrüfungen Prüfer Note Datum May 6, 2001 May 2, 2001 Datum ... ... ... ... 33 Anfragen auf geschachtelten Relationen SELECT s.Name, p.Note FROM StudentenTab s, TABLE(s.absolviertePrüfungen) p; NAME NOTE -------------------- -------------Theophrastos 1.3 Theophrastos 1.7 SQL:1999 (Oracle: '.') SELECT s.Name, p.Pruefer->Name, p.Inhalt->Titel, p.Note FROM StudentenTab s, TABLE(s.absolviertePrüfungen) p; NAME PRUEFER.NAME INHALT.TITEL NOTE -------------------- ------------------------- ----------------------- ------------Theophrastos Sokrates Maeeutik 1.3 Theophrastos Sokrates Ethik 1.7 34 Vererbung in ORDBMS: Spezialisierung von Objekt-Typen Implementiere die Spezialisierungsbeziehung zwischen Angestellten und Professoren (Assistenten) Zunächst auf der Typebene (Substituierbarkeit): CREATE TYPE AngestelltenTyp AS (PersNr INT, Name VARCHAR(20)) NOT INSTANTIABLE; Generelle Angestellte dürfen nicht erzeugt werden CREATE TYPE ProfessorenTyp UNDER AngestelltenTyp AS (Rang CHAR(2), Spezialisierung auf Typebene Raum INT); CREATE TYPE AssistentenTyp UNDER AngestelltenTyp AS (Fachgebiet VARCHAR(20), Boss REF(ProfessorenTyp)); 35 Spezializierung und Inklusion von Tabellen CREATE TABLE AngestelltenTab OF AngestelltenTyp; Inklusion auf Tabellebene CREATE TABLE ProfessorenTab OF ProfessorenTyp UNDER AngestelltenTab INHERIT SELECT PRIVILEGES; CREATE TABLE AssistentenTab OF AssistentenTyp UNDER AngestelltenTab INHERIT SELECT PRIVILEGES; Die Semantik der Inklusion durch Spezialisierung entspricht damit der folgenden SQL View-Definition: CREATE VIEW AngestelltenTab AS SELECT PersNr, Name FROM ProfessorenTab UNION ALL SELECT PersNr, Name From AssistentenTab; 36 Vererbung in ORDBMS: Einfügungen in "Unterrelationen" INSERT INTO ProfessorenTab (PersNr, Name, Rang, Raum) VALUES (2125, 'Sokrates', 'C4', 226), (2126, 'Russel', 'C4', 232), (2137, 'Curie', 'C4', 7); INSERT INTO AssistentenTab (PersNr, Name, Fachgebiet, Boss) VALUES (3002, 'Platon', 'Ideenlehre', SELECT REF(p) FROM ProfessorenTab p WHERE p.PersNr = 2125), (3003, 'Aristoteles', 'Syllogistik', SELECT REF(p) FROM ProfessorenTab p WHERE p.PersNr = 2125), (3004, 'Wittgenstein', 'Sprachtheorie', SELECT REF(p) FROM ProfessorenTab p WHERE p.PersNr = 216); SELECT a.PersNr, a.Name FROM AngestelltenTab Ergebnis enthält sechs Tupel! 37 Benutzer-definierte Column Types (hier: DB2-Syntax) Benutzer-definierte Objekt-Typen lassen sich auch als Attribute in regulären Tabellen einbetten. Beispiel: Definiere einen allg. NotenTyp, leite davon die spezifischeren Typen US_NotenTyp und D_NotenTyp ab: CREATE TYPE NotenTyp AS ( NumWert DECIMAL(3,2), StringWert VARCHAR(20), Land VARCHAR(20) ); CREATE TYPE US_NotenTyp UNDER NotenTyp AS ( WithHonors CHAR(1) ); CREATE TYPE D_NotenTyp UNDER NotenTyp AS ( Lateinisch VARCHAR(20) ); 38 Benutzer-definierte Column Types Es gilt weiterhin das Prinzip der Substituierbarkeit: ein spezifischer Subtyp darf in der Rolle der generellen Typs auftreten: CREATE TABLE Leistungen ( TeilnehmerIn VARCHAR(20), Lehrveranstaltung VARCHAR(20), Note NotenTyp ); Auf die Felder eines strukturierten Column Types wird mittels '..' (SQL:1999: '.') zugegriffen: SELECT TeilnehmerIn, Lehrveranstaltung, Note..Land, Note..NumWert FROM Leistungen 39 Benutzer-definierte Column Types (Konstruktoren) Bevölkern der Tabelle Leistungen und Instantiierung strukturierter Typen (setter-Methoden sind impliziert definiert): INSERT INTO Leistungen VALUES ( 'Feuerbach', 'Java', US_NotenTyp()..Land('USA')..NumWert(4.0) ..StringWert('excellent')..withHonors('y') ); INSERT INTO Leistungen VALUES ( 'Feuerbach', 'C++', D_NotenTyp()..Land('USA')..NumWert(1.0) ..StringWert('sehr gut')..Lateinisch('summa cum laude') ); 40 Test auf dynamische Typen In SQL:1999 läßt sich der dynamische Typ eines Ausdrucks mittels IS [ NOT ] OF ( t1, t2, … ) testen: SELECT TeilnehmerIn, Note..NumWert FROM Leistungen WHERE Note IS OF ( US_NotenTyp ); selektiert ein Tupel Achtung: Note..withHonors wäre nicht typkorrekt. (Warum?) SELECT TeilnehmerIn, TREAT(Note AS US_NotenTyp)..withHonors FROM Leistungen WHERE Note IS OF ( US_NotenTyp ); SELECT TeilnehmerIn, CASE WHEN Note IS OF ( US_NotenTyp ) THEN TREAT(Note AS US_NotenTyp)..withHonors ELSE '?' END AS Honors FROM Leistungen 41