1.2. SQL 1.2.1. Die 3 Sprachebenen von SQL SQL (=Structured Query Language) ist eine Sprache mit 3 Arten von Befehlen: 1. Befehle zur Datenbankdefinition und Tabellendefinition (DDL=Datendefinitionssprache): Der SQL-Befehl: create database ti7ws96 ; definiert eine Datenbank mit dem Namen ti7ws96. Dieser Befehl erfordert in der Regel besondere Privilegien, z.B. das DBA-Privileg. Wenn die Datenbank definiert ist, kann man sich anmelden (=connect database). Sobald man mit einer Datenbank verbunden ist, kann man auf existierende Tabellen zugreifen oder eigene Tabellen definieren. Beispiel 1: create Table Student (Mnr int, Vorname char(20), Name char(20), Fbr char(3) ) ; legt eine Tabelle Student mit 4 Attributen an. 2. Befehle zur Datenmanipulation (DML=Datenmanipulationssprache), z.B: insert into Student values ( 1000 , 'Anna' , 'Arm' , 'ti' ) ; insert into Student values ( 1001 , 'Rita' , 'Reich' , 'ti' ) ; insert into Student values ( 1001 , 'Peter' , 'Reich' , 'ti' ) ; insert into Student values ( 1001 , 'Peter' , 'Petersen' , 'ie' ) ; delete from Student S where S.Name = 'Arm' ; Die ersten vier Befehle fügen jeweils ein Tupel in die Relation Student ein, der delete-Befehl löscht alle Tupel aus der Relation, deren Nachname gleich 'Arm' ist. 3. Befehle, um Anfragen an die Datenbank zu stellen, gehören zur Anfragesprache (QL=Query Language) , z.B.: select S.Name from Student S where S.Fbr = 'ti' ; selektiert (=where) alle Studenten, die im Fachbereich 'ti' sind und projioziert (=select) auf deren Nachnamen. Werden die Befehle dieses Abschnitts der Reihe nach eingegeben, liefert der letzte Befehl folgende Ausgabe: Reich Reich Denn die Daten von Anna Arm sind bereits gelöscht, und es gibt 2 Studenten mit Namen 'Reich' im Fachbereich 'ti'. 1.2.2. Die Anfragesprache von SQL und der relationale Tupelkalkül Die Anfragesprache von SQL basiert auf dem relationalen Tupelkalkül. Im Tupelkalkül wird für jede beteiligte Relation eine Tupel-Variable (im folgenden Beispiel S) eingeführt. Teilmengen einer Relation werden durch Formeln beschrieben, die diese Tupelvariablen benutzen. Beispiel: select S.Name from Student S where S.Fbr = 'ti' ; beschreibt die Menge aller der Tupel S, die in der Datenbankrelation Student abgespeichert sind und im Attribut Fbr den Wert 'ti' haben. Im Gegensatz zum Domänenkalkül wird für jede beteiligte Relation eine Variable eingeführt, nicht aber für jede Domäne (jedes Attribut) einer beteiligten Relation. Wenn es nur eine Relation gibt, aus der die Attribute Name und Fbr kommen können, so kann die Tupelvariable S auch weggelassen werden, und man schreibt kürzer: select Name from Student where Fbr = 'ti' ; Literatur: Silberschatz [u.a.]: Database System Concepts, McGraw Hill, 1997. 1.2.3. Die Algebra-Operationen in SQL Selektion und Projektion: Für das folgende Beispiel nehmen wir an, es existiert eine Relation Student, die die Attribute Mnr (für Matrikelnr), Vorname, Name und Fbr hat. Die Query: select * from Student S where S.Fbr = 'ti' ; selektiert (=where) alle die Tupel S der Relation Student, deren Attribut Fbr den Wert 'ti' hat. Der * bedeutet: zeige alle Attribute an. Will man bestimmte Attribute aus dem Ergebnis herausprojizieren, so muß man diese Attribute in einer Projektionsliste aufführen. DieQuery: select S.Vorname,S.Name from Student S where S.Fbr = 'ti' ; liefert nur Vornamen und Namen aller Tupel S der Relation Student, für die das Attribut Fbr den Wert 'ti' hat, d.h., die anderen Attribute entfernt die Projektion (=select). Join und Kartesisches Produkt: Angenommen es gibt eine zweite Relation Fach mit Attributen Fbr und Vorlesung, die beschreibt, welche Vorlesung von welchem Fachbereich angeboten wird. Die Anfrage "Wer mu ß welche Vorlesung hören ?" erfordert einen Join beider Relationen Student und Fach über das gemeinsame Attribut Fbr: select S.Vorname, S.Name, F.Vorlesung from Student S, Fach F where S.Fbr = F.Fbr ; Oder man fragt unabhängig von Pflichten "Wer könnte was hören ?" nach dem kartesischen Produkt beider Relationen projiziert auf die Attribute Vorname, Name und Vorlesung : select S.Vorname, S.Name, F.Vorlesung from Student S, Fach F ; Der Vergleich der beiden letzten Queries zeigt, daß der Join im Tupelkalkül ähnlich wie in der relationalen Algebra durch explizites Gleichsetzen zweier Attribute gebildet wird ( hier : S.Fbr = F.Fbr ) , also anders als im Domänenkalkül, in welchem man eine Domänenvariable mehrfach verwendet. Interessiert man sich nur für Namen und Vornamen der Studenten, die das Fach Datenbanken hören müssen, so wird nur auf die Attribute einer der beiden am Join beteiligten Relationen projiziert ( = Semi-Join ). Statt select S.Vorname, S.Name from Student S, Fach F where S.Fbr = F.Fbr and F.Vorlesung = 'Datenbanken' ; kann man auch einen geschachtelten SQL-Befehl verwenden: select S.Vorname, S.Name from Student S where exists ( select * from Fach F where S.Fbr = F.Fbr and F.Vorlesung = 'Datenbanken' ) ; Dabei steht exists für den Existenz-Quantor. Der zweite(=innere) select-Befehl wird auch Subquery genannt. Vereinigung Die Vereinigung zweier Relationen Kompaktkurs und Grundlagenkurs wird mit dem Vereinigungsoperator UNION gebildet ( select * from Kompaktkurs K ) UNION ( select * from Grundlagenkurs G ) ; Hier wird sowohl die erste als auch die zweite Relation benutzt, um Antworten auf die Anfrage zu finden. In beiden Relationen auftretende Tupel werden nur einmal angezeigt. Will man doppelt auftretende Tupel mehrfach sehen, muß man (in SQL-Talk) UNION ALL benutzen: ( select * from Kompaktkurs K ) UNION ALL ( select * from Grundlagenkurs G ) ; Durchschnitt Der Durchschnitt zweier Relationen Kompaktkurs und Grundlagenkurs wird wie folgt gebildet (vorausgesetzt Fbr und Vorlesung sind alle Attribute beider Relationen): select * from Kompaktkurs K where exists ( select * from Grundlagenkurs G where K.Fbr = G.Fbr and K.Vorlesung = G.Vorlesung ) ; Wenn es einen kürzeren Schlüssel gibt, braucht man in der where-Klausel nicht alle Attribute gleichzusetzen, sondern es genügt, alle Schlüsselattribute gleichzusetzen. Differenz Die Differenz zweier Relationen kann mit dem NOT-Operator gebildet werden. ZumBeispiel liefert folgende Anfrage die Differenzmenge zwischen der Relation Kompaktkurs und der Relation Grundlagenkurs, also die Kompaktkurse, die keine Grundlagenkurse sind (vorausgesetzt Fbr und Vorlesung sind alle Attribute beider Relationen). select * from Kompaktkurs K where NOT exists ( select * from Grundlagenkurs G where K.Fbr=G.Fbr and K.Vorlesung=G.Vorlesung ) ; Umbenennen von Attributen Der Befehl select S.Name as Nachname from Student S ; benennt das projizierte Attribut Name in Nachname um. Zuweisung Jedes Zwischenergebnis kann wieder in einer Tabelle gespeichert werden, in SQL -Talk dadurch, daß man zuerst eine Tabelle für das Zwischenergebnis anlegt und anschließend die gewünschten Tupel in diese Tabelle einfügt. Beispiel: create table TiStudent( Vorname char(20) , Name char(20) ) ; insert into TiStudent select S.Vorname, S.Name from Student S where S.Fbr = 'ti' ; Diese neue Tabelle TiStudent hat nur die Attribute Vorname und Name und enthält nur Vor- und Nachnamen der Studenten aus dem Fachbereich ti. Relationale Vollständigkeit Da die vorgestellte Teilmenge von SQL alle Grundoperationen der relationalen Algebra (Vereinigung, Differenz, kartesisches Produkt, Selektion und Projektion und Umbenennen von Attributen) unterstützt, ist sie relational vollständig. 1.2.4. Weitere SQL-Queries in Beispielen Mit ALL bzw. ANY kann man allquantifizierte oder existenzquantifizierte Anfragen stellen, z.B.: select * from Student S where S.Mnr >= ALL (select S2.Mnr from Student S2); selektiert (=where) die Studenten S, deren Mnr maximal ist, d.h., größer oder gleich der Mnr aller anderen Studenten S2 ist. Die Anfrage select * from Kurs K where K.Fbr = ANY (select S.Fbr from Student S) ; selektiert die Kurse K, die von einem Fachbereich angeboten werden, zu dem auch mindestens ein (ANY) Student gehört. Erlaubt sind auch >ANY, <ANY, usw. Statt =ANY hätte man auch IN schreiben dürfen, d.h., die Anfrage select * from Kurs K where K.Fbr IN (select S.Fbr from Student S) ; fragt nach denselben Kursen, muß also immer dasselbe Ergebnis liefern wie die vorige Anfrage. Will man doppelt auftretende Tupel im Anfrageergebnis unterdrücken, kann man SELECT DISTINCT benutzen. SELECT DISTINCT S.Name from Student S where S.Fbr = 'ti' ; Um Strings zu suchen, kann man das Jokerzeichen '_' oder den Jokerstring '%' (% steht für 0 bis beliebig viele Zeichen) in Stringketten verwenden, die mit LIKE verglichen werden. Beispiel: select * from student S where S.Name LIKE '_ei%' ; Diese Anfrage selektiert die Studenten, deren Nachname als 2. Buchstabe 'e' und als 3. Buchstaben 'i' enthalten. 1.2.5. Gruppierung (GROUP BY und HAVING) SQL bietet die Möglichkeit, die Tupel einer Relation in Gruppen zusammenzufassen und Anfragen über diese Gruppen zu stellen. Beispiel: Die Anfrage select S.Fbr, count(S.Fbr) from Student S group by Fbr ; faßt Studenten nach Fachbereichen zu Gruppen zusammen und zeigt den Fachbereich jeder Gruppe nur einmal an. Durch count(Fbr) wird angezeigt, welcher Fbr wie oft in der Student -Relation auftritt, z.B. : S.Fbr count(S.Fbr) ===== ========= ti 2 ie 1 Auch über Gruppen kann man weitere Auswahlbedingungen stellen. In diesem Fall benutzt man das Schlüsselwort HAVING. Beispiel: Die Anfrage select Fbr, count(Fbr) from Student group by Fbr having count(*) >= 2 ; selektiert nur die Namen der Fachbereiche aus der Relation Student, die in der Relation Student mindestens 2 mal genannt sind, und gibt an, wie oft sie genannt sind: Fbr count(Fbr) === ======= ti 2 Die Having-Klausel stellt immer nur Selektionsbedingungen an eine Gruppe, niemals jedoch eine Selektionsbedingung an einzelne Tupel. Für Gruppen sind außer COUNT weitere Aggregatfunktionen definiert: SUM berechnet die Summe AVG berechnet den Durchschnittswert MIN berechnet das Minimum MAX berechnet das Maximum der gruppierten Werte. 1.2.6. Nullwerte Wenn ein Attributwert nicht bekannt ist, kann man einen Nullwert NULL eintragen. Dieser Nullwert wird bei Anfragen besonders behandelt. Beispiel: insert into Student values( 1007 , NULL , 'Gast' , 'ti' ) ; Der Vorname von Student Gast ist nicht bekannt. Trotzdem ist bekannt, daß es einen Studenten mit Matrikelnr 1007 und Nachname Gast im Fachbereich ti gibt. Bei der Anfrage select S.Name from Student S where S.Vorname = 'Peter' ; wird der Student Gast nicht mit ausgegeben, da nicht sicher ist, ob er mit Vornamen 'Peter' heißt. Bei der Anfrage select S.Name from Student S where S.Vorname <> 'Peter' ; wird der Student Gast ebenfalls nicht ausgegeben, da nicht sicher ist, daß er nicht mit Vornamen 'Peter' heißt. Beide Vergleiche S.Vorname = 'Peter' und S.Vorname <> 'Peter' werden bei einem Nullwert als falsch interpretiert. Nicht einmal die Anfrage select S.Name from Student S where S.Vorname <> 'Peter' OR S.Vorname = 'Peter' ; liefert diesen Student. Erst die Anfrage select S.Name from Student S; liefert diesen Student. Wegen möglicher Nullwerte, darf also die vorherige Anfrage mit ORVerknüpfung nicht zur letzten Anfrage vereinfacht werden. Nullwerte lassen sich abfragen, z.B.: select S.Name from Student S where S.Vorname IS NULL ; Die übrigen Studenten, deren Vornamen bekannt sind, bekommt man am einfachsten durch den IS NOT NULL-Operator. Beispiel: select S.Name from Student S where S.Vorname IS NOT NULL ; In der gleichen Weise können auch zwei Nullwerte gleich oder verschieden sein. SQL berechnet jeweils als Ergebnismenge nur die Tupel, die die Anfrage garantiert erf üllen. Für Nullwerte gelten die Rechenregeln: 1. NULL + x = NULL und NULL * 0 = NULL 2. Vergleiche mit Nullwert haben immer den Wert Unknown 3. logische Operationen propagieren unknown, d.h. Unknown AND true = Unknown , Unknown OR false = Unknown , Unknown AND Unknown = Unknown , Unknown OR Unknown = Unknown , NOT Unknown = Unknown . 4. Tupel mit ... where Unknown ; werden nicht ins Ergebnis übernommen. 5. Bei der Gruppierung wird NULL als eigener Wert behandelt. Es gibt in SQL keine Möglichkeit, 2 Nullwerte als gleichwertig zu setzen, z.B., ich kenne zwar den Fachbereich von Anna Arm und Rita Reich nicht, weiß aber, daß sie in demselben Fachbereich studieren. Wird in beiden Tupeln der Attributwerte für Fachbereich auf NULL gesetzt, so werden die Tupel in allen Anfragen behandelt, als seien die Attributwerte verschieden. Anders gesagt, bei der Anfrage Wer studiert in demselben Fachbereich wie Anna Arm? select * from Student S where S.Fbr = ( select S2.Fbr from Student S2 where S2.Vorname='Anna' and S2.Name='Arm' and S.Fbr=S2.Fbr ) erhält man jeweils nur ein Ergebnis: Anna Arm selbst. 1.2.7. Die Datenmanipulationssprache von SQL 1.2.7.1. Einfügen Ein einzelner Student wird mit folgendem Befehl eingef ügt: insert into Studenten values( 1005 , 'Norbert' , 'Neu' , 'ti' ) ; Einfügen einer Tupelmenge ist ebenfalls möglich: insert into Kompaktkurs select * from grundlagenkurs ; Hier sind beliebige select-Befehle möglich. Erforderlich ist aber, daß die Projektionsliste selektierter Tupel identisch ist mit der Attributliste der Relation, in die eingefügt werden soll. 1.2.7.2. Löschen Löschen eines Tupels (des Tupels mit dem Schlüsselwert 1005 für Mnr) : delete from Student S where S.Mnr = 1005 ; Löschen einer Tupelmenge delete from Fach F where F.Fbr = 'Leichtbau' ; Hier sind beliebige where-Klauseln wie auch beim select-Befehl möglich. Ohne where-Klausel wird die ganze Relation gelöscht, und es bleibt eine leere Tabelle zurück. Alle Fächer werden z.B. gelöscht mit: delete from Fach F ; 1.2.7.3. Ändern Ändern eines Tupels (Anna Arm ändert ihren Nachnamen bei der Heirat): update Student S set S.Name = 'Reich' where S.Mnr = 1000 and S.Vorname = 'Anna' ; Ändern einer Tupelmenge (Gehaltserhöhung für Angestellte A in Abteilung 44) : update Angestellte A set A.Gehalt = A.Gehalt * 1.05 where A.Abteilung = 44 ; 1.2.8. Bindvariablen für den Datentransfer zu SQL SQL-Befehle können über sogenannte Bind-Variablen mit ihrer Umgebung kommunizieren. In der Regel sind das Programme in C,Cobol oder einer anderen Programmiersprache. Bindvariablen können aber auch in der interaktiven Umgebung von SQL-Talk dazu benutzt werden, Daten direkt einzugeben. Beispiel: insert into Student values ( :1 , :2 , :3 , :4 ) \ 1005, Norbert, Neu,ti 1006, Hugo, Held, ti 1007, Manfred, Meier, ie 1008, , Unbekannt, ie / Die Datensektion wird mit einem Backslash (\) an der ersten Stelle einer ansonsten leeren Zeile begonnen und mit einem Slash (/) an der ersten Stelle einer ansonsten leeren Zeile beendet. Die Attributwerte in der Datensektion sind durch ein Komma bzw. einen Zeilenumbruch getrennt. Die Datensektion enthält 4 einzufügende Tupel mit je 4 Attributwerten. Die Bindvariablen :1 bis :4 beziehen sich auf die Position der Attributwerte: so wird :1 der Reihe nach an 1005 bis 1008 gebunden. Nullwerte werden durch zwei Kommas begrenzt: so wird :2 im letzten Tupel mit einem Nullwert besetzt. Bindvariablen sind in allen Befehlen erlaubt, wo auch Werte erlaubt sind. Weiteres Beispiel: update konto set betrag = betrag + :1 where kontonr = :2 \ 1000.00 , 101 423.50 , 102 6000.00 , 103 / In Programmiersprachen können auch Programmvariablen aus dem Umgebungsprogramm in gleicher Weise benutzt werden. Beispiel: insert into student values( :Mnr , :Vorname , :Name , :Fbr ) ; wobei Mnr, Vorname, Name und Fbr Variablen aus dem Umgebungsprogramm (z.B. aus einem C Programm) sind. 1.2.9. Schemadefinition in SQL (1.Teil) Definition oder Änderung des Datenbankschemas sind ganz seltene Operationen. Da häufig nicht nur die Implementierung von Views sondern auch zahlreiche Anwendungsprogramme betroffen sind, werden solche Änderungen häufig nur von privilegierten Benutzern, den Datenbankadministratoren vorgenommen. SQL enthält folgende Sprachkonstrukte zur Definition oder Änderung des Datenbankschemas: Anlegen, Löschen und Ändern von Relationenschematas und Views, Vergabe von Zugriffsrechten. Eine Tabelle Student wird angelegt durch den Befehl create table Student(Mnr int, Vorname char(20), Name char(20), Fbr char(3) ); Damit ist festgelegt, daß die Tabelle Student 4 Attribute hat, Mnr vom Typ Integer und Vorname, Name und Fbr vom Typ String, wobei für die Strings noch Maximallängen angegeben wurden. In den meisten SQL-Dialekten bedeutet diese Definition, daß Mnr, Vorname, Name und Fbr Nullwerte annehmen dürfen, in Sybase 11.5 sqsh bedeutet es jedoch, daß Nullwerte verboten sind. Will man Nullwerte für Vorname, Name und Fbr in Sybase 11.5 sqsh explizit erlauben, so schreibt man: create table Student(Mnr int, Vorname char(20) NULL, Name char(20) NULL, Fbr char(3) NULL); Um Nullwerte für Mnr, Vorname und Name in anderen SQL-Dialekten explizit verbieten, schreibt man create table Student(Mnr int NOT NULL, Vorname char(20) NOT NULL, Name char(20) NOT NULL, Fbr char(3) ); Folgende Attributtypen sind erlaubt: int Integer char(N) String, maximal N Zeichen lang, in der Regel muß N < 255 sein varchar(N) variabel langer String, max. N Zeichen lang, in SQL-Talk muß N<255 sein long langes Feld (max. Größe z.B. 1GB), manche Datenbanksysteme erlauben nur ein langes Feld pro Tabelle. Lange Felder dürfen nicht Teil eines Schlüssels sein. real real-Wert date Datum Tabellen können verändert werden, indem man Attribute hinzufügt oder entfernt, Integritätsbedingungen hinzufügt oder entfernt oder Defaultwerte hinzufügt oder entfernt. Durch den Befehl alter table Student add semesterzahl int ; wird eine zusätzliche Spalte Semesterzahl angelegt. Wenn kein Defaultwert vorgegeben ist, werden Nullwerte einsetzt. Tabellen können zudem gelöscht werden. Beispiel: drop table student ; löscht die Tabelle Student und ihren Inhalt. 1.2.10. Viewdefinition in SQL Eine View (=Sicht=virtuelle Relation) ist eine nicht physikalisch gespeicherte Relation. Für den Benutzer sieht eine View aus wie eine Relation und kann genauso durch Anfragen bearbeitet werden. Damit die Tupel einer View bei Anfragen neu berechnet werden k önnen, muß bei der Definition einer View eine Berechnungsvorschrift mitgegeben werden. Beispiel: create view Studiert as select S.Mnr, S.Vorname, S.Name from Student S ; Views können dazu dienen, Benutzern nur bestimmte Daten zu zeigen und andere Daten zu verbergen. Views können aber auch dazu dienen, für den Benutzer interessante Daten aus mehreren physisch vorhandenen Tabellen zu verknüpfen und in einer einzigen View-Tabelle zusammenzufassen: Beispiel: create view Pflichten_Von as select S.Mnr, S.Vorname, S.Name, F.Vorlesung from Student S, Fach F where S.Fbr = F.Fbr ; Views haben u.a. den Vorteil, daß das physische Datenbankschema geändert werden kann, ohne daß der Benutzer es merkt. Wenn Anwendungsprogramme nur Views benutzen, k önnen die Schemata der darunterliegenden Relationen geändert werden, ohne die Anwendungsprogramme mit ändern zu müssen. Bei Schreiboperationen auf Views gibt es Einschränkungen. Einfügeoperationen auf die View Studiert sind zulässig, weil das Datenbanksystem bei Einfügeoperationen Nullwerte für den Fachbereich in die Student-Relation einträgt. Allgemein gilt: Wenn eine View durch nur eine Relation in der FROM-Klausel definiert wurde, darf man in diese View einfügen. Für die nicht in der View vorhandenen Attribute werden die Attributwerte vom Datenbanksystem auf NULL gesetzt. Löschoperationen auf der View Studiert sind ebenfalls erlaubt, weil das Datenbanksystem bei Löschoperationen in der zugrundeliegenden Student -Relation löscht. Aber Schreiboperationen in der Relation Pflichten_Von, z.B. einfügen oder löschen einer Pflicht sind verboten. Ihre Implementierung durch Änderungen der Relationen Student und Fach ist in der Regel nicht möglich, da die Join-Berechnung sonst falsche Ergebnisse liefert. Allgemein gilt: Wenn eine View eine Aggregatfunktion berechnet (MIN,MAX,SUM,AVG,COUNT) oder im Tupelkalkül aus mehr als einer Relation berechnet wird, darf man in diese View weder einfügen noch löschen. Um Nullwerte zu unterbinden, wird in einigen Datenbanksystemen das Einf ügen oder Löschen von Tupeln in Views generell unterbunden. 1.2.11. Transaktionen in SQL Die einzige Möglichkeit, auf eine Datenbank zuzugreifen, ist über Transaktionen. Jede Datenbankoperation muß zu genau einer Transaktion gehören. Datenbankoperationen, die zusammen ausgeführt werden sollen, werden vom Programmierer in derselben Transaktion zusammengefaßt, z.B. eine Umbuchung (hier sind zwei Konten betroffen, also m üssen 2 Operationen zu einer Transaktion zusammengefaßt werden). Das Datenbanksystem startet mit dem ersten Zugriff eines Programms auf eine Datenbank automatisch eine Transaktion für dieses Programm und beendet beim Programmende die laufende Transaktion. So ist garantiert, daß alle Datenbankzugriffe nur in Transaktionen stattfinden. Im AUTOCOMMIT-Modus wird nach jedem SQL-Befehl eine neue Transaktion gestartet. Ist der AUTOCOMMIT-Modus ausgeschaltet, so gibt es zur Transaktionssteuerung in SQL 2 Befehle: COMMIT und ROLLBACK. COMMIT beendet die laufende Transaktion erfolgreich, erzwingt also die Übernahme der Änderungen in die Datenbank; ROLLBACK setzt die laufende Transaktion zurück, macht also die in dieser Transaktion durchgeführten Änderungen der Datenbank rückgängig. Sowohl nach COMMIT als auch nach ROLLBACK startet das Datenbanksystem für das laufende Programm automatisch sofort wieder eine neue Transaktion. Wenn der Benutzer weder einen COMMIT- noch einen ROLLBACK-Befehl gegeben hat, führt das Datenbanksystem automatisch beim normalen Programmende ein COMMIT und beim abnormalen Programmende ein ROLLBACK durch. 1.2.12. Joins in SQL-92 select * from Student S join Kurs K on S.Fbr = K.Fbr ; S.Mnr S.Vorname S.Name S.Fbr K.Fbr F.Vorlesung 1000 Anna Arm ti ti Mathe1 1000 Anna Arm ti ti Info A 1001 Rita Reich ti ti Mathe 1 1001 Rita Rita ti ti Info A 1003 Peter Petersen ie ie Physik 1 select * from Student S left outer join Kurs K on S.Fbr = K.Fbr ; S.Mnr S.Vorname S.Name S.Fbr K.Fbr F.Vorlesung 1000 Anna Arm ti ti Mathe1 1000 Anna Arm ti ti Info A 1001 Rita Reich ti ti Mathe 1 1001 Rita Rita ti ti Info A 1003 Peter Petersen ie ie Physik 1 1007 Norbert Neu Medienwissenschaften NULL NULL select * from Student S right outer join Kurs K on S.Fbr = K.Fbr ; S.Mnr S.Vorname S.Name S.Fbr K.Fbr F.Vorlesung 1000 Anna Arm ti ti Mathe1 1000 Anna Arm ti ti Info A 1001 Rita Reich ti ti Mathe 1 1001 Rita Rita ti ti Info A 1003 Peter Petersen ie ie Physik 1 NULL Studium Konfliktlösung Generale NULL NULL NULL select * from Student S full outer join Kurs K on S.Fbr = K.Fbr ; S.Mnr S.Vorname S.Name S.Fbr K.Fbr F.Vorlesung 1000 Anna Arm ti ti Mathe1 1000 Anna Arm ti ti Info A 1001 Rita Reich ti ti Mathe 1 1001 Rita Rita ti ti Info A 1003 Peter Petersen ie ie Physik 1 1007 Norbert Neu Medienwissenschaften NULL NULL NULL NULL NULL NULL Studium Konfliktlösung Generale 1.2.13. Rekursion in SQL Im Standard von SQL-92 ist Rekursion nicht enthalten, jedoch gibt es Hertseller-spezifische Spracherweiterungen. In DB2 : with pfad (Start,Ziel ) as ( select Start, Ziel from direkt union all select d.Start , p.Ziel from direkt d , pfad p where d.Ziel = p.Start ) select * from pfad ; Der Befehl with ... as select ... erzeugt eine temporäre rekursive View pfad. Rekursion geht über die relationale Algebra hinaus.