6. Übungsblatt. Für die Übung am Donnerstag, 07. Dezember 2006, von 15:30 bis 17:00 Uhr in 13/222. Aufgabe 1: Eingebettetes SQL am Beispiel Lieferung

Ähnliche Dokumente
AG Datenbanken und Informationssysteme Wintersemester 2006 / 2007

AG Datenbanken und Informationssysteme Wintersemester 2006 / 2007

7. Übungsblatt. Für die Übung am Donnerstag, 14. Dezember 2006, von 15:30 bis 17:00 Uhr in 13/222.

Grundlagen von Datenbanken SS 2010 Kapitel 8: Datenbank-Einbettung in Programmiersprachen Prof. Dr. Stefan Böttcher Universität Paderborn

Datenbanksysteme 2 Fachbereich Angewandte Informatik WS 11/12 Dipl.-Inf. Christian Pape. 6. Übung

Kapitel 10. JDBC und SQLJ. Prof. Dr. Wolfgang Weber Vorlesung Datenbanken 1

Java Database Connectivity (JDBC) Walther Rathenau Gewerbeschule 1

JDBC. Es kann z.b. eine ODBC-Treiberverbindung eingerichtet werden, damit das JAVA-Programm auf eine ACCESS-DB zugreifen kann.

Client/Server-Programmierung

Datenbankschnittstellen erlauben Zugriff auf Datenbank aus einer externen Anwendung

Willkommen. Datenbanken und Anbindung

Client/Server-Programmierung

Java: MySQL-Anbindung mit JDBC.

Oracle: Abstrakte Datentypen:

seit Java 1.1 Bestandteil der API: packages java.sql, javax.sql

Datenbanksysteme noch Kapitel 7: SQL Vorlesung vom Oliver Vornberger. Institut für Informatik Universität Osnabrück

Klausur Datenbanken II

Kapitel 9. Embedded SQL. Prof. Dr. Wolfgang Weber Vorlesung Datenbanken 1

Datenbanksysteme I Datenbankprogrammierung Felix Naumann

Webbasierte Informationssysteme

vs. Fehler zur Übersetzungszeit

AG Datenbanken und Informationssysteme Wintersemester 2006 / Übungsblatt

Datenbanken SQL JDBC. Programmieren II. Dr. Klaus Höppner. Hochschule Darmstadt Sommersemester / 21

Universität Augsburg, Institut für Informatik WS 2011/2012 Prof. Dr. W. Kießling 09. Dez Dr. M. Endres, Dr. S. Mandl, F. Wenzel Lösungsblatt 6

Wie kommen die Befehle zum DBMS

Webbasierte Informationssysteme

Beispiel: DB-Mock (1/7)

Programmieren II. Beispiele für RDBMS. Relationale Datenbanken. Datenbanken SQL. Dr. Klaus Höppner JDBC. Hochschule Darmstadt SS 2008

Datenbankentwurf & Datenbankzugriff mit JDBC. Georg Köster Sven Wagner-Boysen

JDBC. Java DataBase Connectivity

Einführung in JDBC. IFIS Universität zu Lübeck

1a) SQL Stored Procedure via IDs

Datenbanksysteme I Übung: JDBC. Jana Bauckmann

Datenbanksysteme 2011

DB-Programmierung. Lehr- und Forschungseinheit Datenbanken und Informationssysteme 1. Ziele. DB2 Zugriff mit Java selbst programmieren

Klausur zur Vorlesung Datenbanksysteme I

Lambda Expressions in Java 8

Gruppe A Bitte tragen Sie sofort und leserlich Namen, Studienkennzahl und Matrikelnummer ein und legen Sie Ihren Studentenausweis

Entwicklungsumgebung für die Laborübung

RELATIONONALE DATENBANKEN MIT JDBC

Kapitel DB:VI (Fortsetzung)

Ho Ngoc Duc IFIS - Universität zu Lübeck

Java Database Connectivity-API (JDBC)

Universität Augsburg, Institut für Informatik WS 2006/2007 Dr. W.-T. Balke 11. Dez M. Endres, A. Huhn, T. Preisinger Lösungsblatt 7

Datenbankschnittstellen erlauben Zugriff auf Datenbank aus einer externen Anwendung

Oracle & Java HOW TO

Wie kommen die Befehle zum DBMS

Praktische SQL-Befehle 2

TU München, Fakultät für Informatik Lehrstuhl III: Datenbanksysteme Prof. Alfons Kemper, Ph.D.

Java Database Connectivity-API (JDBC)

11. Datenbankschnittstellen

TU München, Fakultät für Informatik Lehrstuhl III: Datenbanksysteme Prof. Alfons Kemper, Ph.D.

UNIVERSITÄT ULM Fakultät für Ingenieurswissenschaften und Informatik Institut für Datenbanken und Informationssysteme

Datenbanksysteme 2013

Java und Datenbanksysteme Datenbankanbindung mit JDBC

GML und Bibliothek oracle.sdoapi

JDBC. Allgemeines ODBC. java.sql. Beispiele

Einbettung in SQL. Zwei Prinzipien: (1) Statische Einbettung

Labor 3 - Datenbank mit MySQL

Musterlösung Übungsblatt 11

Datenbanksysteme II SS 2017 Übungsblatt 3 Teillösung

Datenbanksysteme I. Aufgabe 1: Erstellen einer Multimedia-Datenbank. Grundlage sind wiederum bereits implementierte Methoden aus Übungsblatt 6:

Anwendungsentwicklung für relationale Datenbanken setzt voraus, dass prozedurale Abläufe programmiert werden können!

Datenmodelle und Datenbanken 2

GROUP BY, HAVING und Sichten

SQLJ. Standardisierte Java-DB. DB-Schnittstelle. Spezifikationen. Oracle, IBM, Informix, Sybase,, Tandem, Sun, Microsoft stehen dahinter

11 Anwendungsprogrammierung

TU München, Fakultät für Informatik Lehrstuhl III: Datenbanksysteme Prof. Alfons Kemper, Ph.D.

Kapitel 8: Datenintegrität

Softwareentwicklung mit JAVA EE

Universität Augsburg, Institut für Informatik WS 2008/2009 Prof. Dr. W. Kießling 23. Nov Dr. A. Huhn, M. Endres, T. Preisinger Lösungsblatt 5

Exercises for the course Databases and Information Systems I WS 2006/2007 Special exercise JDBC

Database. Creates. -- Kunde(knr, nname, vname, adresse:adresse.aid) CREATE TABLE Kunde ( NUMERIC(13) PRIMARY KEY,

3. Datenbankzugriff (JDBC) Grundlagen der Programmierung II (Java)

5. Übungsblatt. Für die Übung am Donnerstag, 27. N ovember 2008 von 15:30 bis 17:00 Uhr in 13/222.

Betreutes Programmieren Vorlesung Informatik II, Blatt 7 Musterlösung

PHP- Umgang mit Datenbanken (1)

PROGRAMMIERPROJEKT 2016 VERWENDETE TECHNOLOGIEN

Universität Augsburg, Institut für Informatik WS 2009/2010 Prof. Dr. W. Kießling 18. Dez Dr. A. Huhn, F. Wenzel, M. Endres Lösungsblatt 8

Übung 6. Tutorübung zu Grundlagen: Datenbanken (Gruppen Do-T24 / Do-T31 WS 2016/2017)

SQL Tutorium Documentation

Hauptschritte einer JDBC-App

Übung Datenbanksysteme I JDBC. Thorsten Papenbrock

DB I S. 1 Relationenalgebra [8 P.] Gegeben seien die folgenden Relationenschemata: Person(PNR, Vorname, Nachname, Geburtsdatum, Wohnort Ort.

Udo Matthias Munz. Datenbanken und SQL. mit. Einführung. Informationstechnik

Datenbanken (Übung 12)

Die Anweisung create table

Internet-Datenbanken

Entwicklungsumgebung für die Laborübung

Kapitel 11: Anwendungsentwicklung

Kapitel 11: Anwendungsentwicklung

Transkript:

AG Datenbanken und Informationssysteme Wintersemester 2006 / 2007 Prof. Dr.-Ing. Dr. h. c. Theo Härder Fachbereich Informatik Technische Universität Kaiserslautern http://wwwdvs.informatik.uni-kl.de 6. Übungsblatt Für die Übung am Donnerstag, 07. Dezember 2006, von 15:30 bis 17:00 Uhr in 13/222. Machen Sie sich mit JDBC (Java Database Connectivity) vertraut, um die Programmieraufgaben mit Java und JDBC zu bearbeiten. Ergänzend zur Vorlesung finden Sie einen Verweis auf die Online-Dokumentationen von JDBC, wie etwa JDBC-Technology Guide: Getting Started, unter den Online-Ressourcen auf der Website zur Vorlesung http://wwwdvs.informatik.uni-kl.de/courses/dbaw. Aufgabe 1: Eingebettetes SQL am Beispiel Lieferung Gegeben seien folgende Relationen: LIEFERANT (LNR, LNAME, STATUS, ORT) PROJEKT (PNR, PNAME, ORT) LIEFERUNG (LNR, TNR, PNR, MENGE) TEIL (TNR, TNAME, FARBE, GEWICHT) Skizzieren Sie ein Programm mit eingebetteten SQL-Anweisungen, das alle Lieferanten in der Reihenfolge ihrer Lieferantennummer ausgibt. Zu jedem Lieferanten soll direkt eine nach den Projektnummern sortierte Liste aller Projekte ausgegeben werden, die von diesem Lieferanten beliefert werden. Seite 1

Lösung: #include <stdio> EXEC SQL INCLUDE sqlca; main(...) { EXEC SQL BEGIN DECLARE SECTION; int cs_lnr; char cs_lname[50]; char cs_status[20]; char cs_ort[50]; int cj_pnr; char cj_pname[50]; char cj_ort; EXEC SQL END DECLARE SECTION; EXEC SQL DECLARE CS CURSOR FOR SELECT LNR, NAME, STATUS, ORT FROM LIEFERANT ORDER BY LNR; EXEC SQL DECLARE CJ CURSOR FOR SELECT DISTINCT P.PNR, P.NAME, P.ORT FROM LIEFERUNG L, PROJEKT P WHERE L.PNR = P.PNR AND L.LNR = :cs_lnr ORDER BY P.PNR; EXEC SQL CONNECT TO testdb; EXEC SQL OPEN CS; do { EXEC SQL FETCH CS INTO :cs_lnr, :cs_lname, :cs_status, :cs_ort; if (sqlca.sqlcode!= 100) { // Ausgabe Lieferant... EXEC SQL OPEN CJ; do { EXEC SQL FETCH CJ INTO :cj_pnr, cj_pname, cj_ort; if (sqlca.sqlcode!= 100) { // Ausgabe Projekt... else { EXEC SQL CLOSE CJ; break; while (true); else { EXEC SQL CLOSE CS; break; while (true); EXEC SQL DISCONNECT; Seite 2

Aufgabe 2: Eingebettetes SQL mit Rekursion, Beispiel Mitarbeiter-Hierarchie In der folgenden DB wird eine Mitarbeiterhierarchie in der üblichen Weise dargestellt: MA (MANR, MANAME, MANAGER, GEHALT) Skizzieren Sie eine Prozedur, die eine Managernummer als Eingabe-Parameter erhält und das Durchschnittsgehalt aller in der Hierarchie (evtl. über mehrere Stufen) untergeordneten Mitarbeiter berechnet. Lösung: Die nun zunächst folgende Lösung ist falsch! (Warum?) PROCEDURE AVG_GEHALT ( IN_MANR : INTEGER) : REAL; VAR count_ma : INTEGER; (* globale Var. zum Zaehlen aller Mitarbeiter *) geh_summe : REAL; PROCEDURE GEHALT_SUMME ( IN_MANR : INTEGER ) : REAL; (*berechnet die Gehaltssumme aller in_manr untergebenen Mitarbeiter*) VAR manr : INTEGER; geh, sum_geh : REAL; EXEC SQL DECLARE C0 CURSOR FOR SELECT MANR, GEHALT FROM MA WHERE MANAGER = :IN_MANR; BEGIN EXEC SQL OPEN C0; sum_geh := 0.0; EXEC SQL FETCH C0 INTO :manr, :geh; WHILE SQLSTATUS # NOTFOUND DO sum_geh := sum_geh + geh; INC(count_ma); sum_geh := sum_geh + GEHALT_SUMME(manr); EXEC SQL FETCH C0 INTO manr, geh; END (*WHILE*) EXEC SQL CLOSE C0; RETURN sum_geh; END GEHALT_SUMME; BEGIN count_ma := 0; geh_summe := GEHALT_SUMME(IN_MANR); IF count_ma > 0 THEN RETURN ( geh_summe / count_ma) ELSE RETURN 0.0; END; END AVG_GEHALT; Seite 3

KORREKT ist folgende Lösung: PROCEDURE AVG_GEHALT ( IN_MANR : INTEGER) : REAL; VAR count_ma : INTEGER; (* Zaehlen aller Mitarbeiter *) geh_summe : REAL; (* Summieren der Einzelgehälter *) PNR_Stack : INT_Stack; (* Stack-Var. vom abstrakten Datentyp INT_Stack (INTEGER-Werte in Form eines Stacks organisiert und mit den üblichen Funktionen verwaltet) zum Speichern der noch abzuarbeitenden Mitarbeiter *) akt_manr : INTEGER; PROCEDURE GEHALT_TEILSUMME ( IN_MANR : INTEGER ); (* berechnet die Gehaltssumme aller IN_MANR direkt untergebenen Mitarbeiter und speichert deren PNR im PNR_Stack *) VAR manr : INTEGER; geh : REAL; EXEC SQL DECLARE C0 CURSOR FOR SELECT MANR, GEHALT FROM MA WHERE MANAGER = :IN_MANR; BEGIN EXEC SQL OPEN C0; EXEC SQL FETCH C0 INTO :manr, :geh; WHILE SQLSTATUS # NOTFOUND DO PUSH(PNR_Stack, manr); geh_summe := geh_summe + geh; INC(count_ma); EXEC SQL FETCH C0 INTO :manr, :geh; END (*WHILE*) EXEC SQL CLOSE C0; RETURN; END GEHALT_TEILSUMME; BEGIN count_ma := 0; geh_sum := 0; INIT (PNR_Stack); PUSH (PNR_Stack, IN_MANR); WHILE NOT EMPTY (PNR_Stack) DO akt_manr := POP (PNR_Stack); GEHALT_TEILSUMME (akt_manr); END; IF count_ma > 0 THEN RETURN ( geh_summe / count_ma) ELSE RETURN 0.0; END; END AVG_GEHALT; Seite 4

Aufgabe 3: JDBC Gegeben sei eine DB, die folgende Relationen enthält: LIEFERANT (LNR, LNAME, STATUS, ORT) PROJEKT (PNR, PNAME, ORT) LIEFERUNG (LNR, TNR, PNR, MENGE) TEIL (TNR, TNAME, FARBE, GEWICHT) Schreiben Sie mit Hilfe von JDBC ein Java-Programm, das alle Lieferanten in der Reihenfolge ihrer Lieferantennummer ausgibt. Zu jedem Lieferanten sollen unmittelbar alle die von diesem Lieferanten belieferten Projekte in der Reihenfolge ihrer Projektnummer aufgelistet werden. Dabei soll weiterhin zu jedem Projekt eine nach den Teilenummern sortierte Liste aller Teile ausgegeben werden, die für dieses Projekt vom jeweiligen Lieferanten geliefert werden. Ihr Programm soll zwei Eingabeparameter erhalten: Benutzername und Passwort, die für die DB-Verbindung benötigt werden. Lösung: import java.sql.*; public class ShowSuppliers { public static void main (String [] argv) { url = "jdbc:db2:demodb"; // URL für die JDBC-Ver- String bindung String user, passwd; Connection conn; Statement stmt; PreparedStatement pstmt1, pstmt2; ResultSet rs1, rs2, rs3; String lnr, pnr; // Pruefe Eingabeparameter fuer die DB-Verbindung if (argv.length!= 2) { System.out.println ("Falsche Parameterangaben!"); System.exit (-1); user = argv[0]; passwd = argv[1]; try { // Lade JDBC-Treiber und erzeuge Verbindungsobjekt Class.forName ("COM.ibm.db2.jdbc.app.DB2Driver"); conn = DriverManager.getConnection (url, user, passwd); // Erzeuge PreparedStatement-Objekte pstmt1 = conn.preparestatement ("SELECT DISTINCT P.pnr, P.pname, P.ort " + "FROM lieferung L, projekt P " + "WHERE L.pnr = P.pnr AND L.lnr =? " + "ORDER BY P.pnr"); Seite 5

pstmt2 = conn.preparestatement ("SELECT T.tnr, T.tname, T.farbe, T.gewicht, L.menge "+ "FROM lieferung L, teil T " + "WHERE L.lnr =? AND L.pnr =? AND L.tnr = T.tnr " + "ORDER BY T.tnr"); lnr"); // Liste Lieferanten System.out.println ("Lieferantenliste mit Projekten:"); stmt = conn.createstatement (); rs1 = stmt.executequery ("SELECT * FROM lieferant ORDER BY while (rs1.next ()) { lnr = rs1.getstring ("LNR"); System.out.println (lnr + ", " + rs1.getstring ("LNA- ME") + ", " + rs1.getint ("STATUS") + ", " + rs1.getstring ("ORT")); pstmt1.setstring (1, lnr); rs2 = pstmt1.executequery (); // Liste Projekte while (rs2.next ()) { pnr = rs2.getstring ("PNR"); System.out.println (" " + pnr + ", " + rs2.get- String ("PNAME") + ", " + rs2.getstring ("ORT")); pstmt2.setstring (1, lnr); pstmt2.setstring (2, pnr); rs3 = pstmt2.executequery (); // Liste Teile while (rs3.next ()) { System.out.println (" " + rs3.getstring ("TNR") + ", " + rs3.getstring ("TNAME") + ", " + rs3.getstring ("FAR- BE") + ", " + rs3.getfloat ("GEWICHT") + ", " + rs3.getint ("MENGE")); // while rs3 // while rs2 // while rs1 // Schließe Ressourcen stmt.close (); pstmt1.close (); pstmt2.close (); conn.close (); // try catch (ClassNotFoundException e) { System.out.println ("ClassNotFoundException beim Laden von JDBC-Driver: " + e.getmessage ()); catch (SQLException e) { System.out.println ("SQLException: " + e.getmessage()); // main // class Seite 6

Aufgabe 4: JDBC und Metadaten Gegeben sei eine nicht leere relationale Datenbank. Schreiben Sie mit Hilfe von JDBC ein Java-Programm, das für einen als Eingabeparameter eingegebenen Basisrelationennamen zunächst überprüft, ob die Relation in der Datenbank existiert. Ist die Relation vorhanden, so soll die zugehörige vollständige SQL-Anweisung für die Erzeugung der entsprechenden Relation generiert und ausgegeben werden. Die Ausgabe muss den Relationennamen und -attribute mit dem jeweiligen Datentyp und eventueller Längenspezifikation enthalten. Betrachten Sie dabei nur Attribute vom Typ VARCHAR, INTEGER und DECIMAL. Neben einem Relationennamen soll das Programm zwei weitere Eingabeparameter berücksichtigen: Benutzername und Passwort, die für die Verbindung zur Datenbank benötigt werden. Hinweis: Verwenden Sie die getmetadata-methode des Connection-Objekts für den Zugriff auf das DatabaseMetaData-Objekt, mit dessen Methoden Sie dann die benötigten Metadaten abfragen. Lösung: import java.sql.*; public class GenSQLStmt { public static void main (String [] argv) { String url = "..."; // URL für die JDBC-Verbindung String user, passwd; Connection conn; ResultSet rs; DatabaseMetaData dbmd; String tablename, catalogname, schemaname; int columntype; String sqlstring; int i, columnsize; String [] tabletypes = {"TABLE"; // Pruefe Eingabeparameter fuer die DB-Verbindung if (argv.length!= 3) { System.out.println ("Falsche Parameterangaben!"); System.exit (-1); tablename = argv[0]; user = argv[1]; passwd = argv[2]; catalogname = "..." ; // Üblicherweise ist dies der DB-Name schemaname = user; // Üblicherweise ist dies der Benutzer-Name try { // Lade JDBC-Treiber und erzeuge Verbindungsobjekt Class.forName ("..."); // JDBC-Treiber conn = DriverManager.getConnection (url, user, passwd); // Hole DB-Metadaten dbmd = conn.getmetadata (); // Pruefe, ob die Basisrelation in der DB existiert. rs = dbmd.gettables (catalogname, schemaname, tablename, tabletypes); if (rs.next ()) { Seite 7

System.out.println ("Relation \"" + tablename + "\" existiert."); sqlstring = "CREATE TABLE " + tablename + " (\n"; rs.close(); // Hole alle Attributdaten rs = dbmd.getcolumns (catalogname, schemaname, tablename, "%"); // Iteriere ueber die Attributobjekte in rs i = 1; while (rs.next ()) { " "; // Hole Attributnamen if (i > 1) { sqlstring = sqlstring + ",\n"; sqlstring += " " + rs.getstring("column_name") + // Hole Datentyp und -laenge, falls noetig columntype = rs.getint ("DATA_TYPE"); columnsize = rs.getint ("COLUMN_SIZE"); if (columntype == java.sql.types.varchar) { sqlstring += "VARCHAR(" + columnsize + ")"; else if (columntype == java.sql.types.integer) { sqlstring += "INTEGER"; else if (columntype == java.sql.types.decimal) { sqlstring += "DECIMAL(" + columnsize + "," + rs.getint ("DECIMAL_DIGITS") + ")"; i++; // while rs.close(); sqlstring = sqlstring + "\n );"; System.out.println (sqlstring); /if else { System.out.println ("Relation \"" + tablename + "\" existiert nicht."); // Schließe Ressourcen stmt.close(); conn.close (); catch (ClassNotFoundException e) { System.out.println ("ClassNotFoundException beim Laden von JDBC-Driver: " + e.getmessage ()); catch (SQLException e) { System.out.println ("SQLException: " + e.getmessage()); Seite 8

Aufgabe 5: Abbildung von Sicht Operationen auf Tabellen (Basisrelationen) In dieser Aufgabe betrachten wir die Abbildung von SELECT-Anweisungen auf Views. Dazu haben wir in der Vorlesung die schrittweise Ersetzung von View-Definitionen auf Basisrelationen betrachtet. Geben seien die folgenden Relationen: STUDENT(MatrNr, FbNr, Name, Vorname, PruefOrd) MITARBEITER(PersNr, FbNr, Name, Vorname, Gehalt) PROFESSOR(PersNr, Arbeitsgruppe) FACHBEREICH(FbNr, Name, Dekan) mit: STUDENT.FbNr ist Fremdschlüssel auf FACHBEREICH.FbNr, MITARBEITER.FbNr ist Fremdschlüssel auf FACHBEREICH.FbNr, PROFESSOR.PersNr ist Fremdschlüssel auf MITARBEITER.PersNr, FACHBEREICH.Dekan ist Fremdschlüssel auf PROFESSOR.PersNr, MITARBEITER-PROFESSOR-Hierarchie ist abgebildet durch vertikale Partitionierung und die folgenden Sichtdefinitionen: CREATE VIEW StudFbPO96 (MatrNr, Name, Vorname, FbNr, FbName, PO) AS SELECT s.martnr, s.name, s.vorname, f.fbnr, f.name, s.prueford FROM STUDENT s, FACHBEREICH f WHERE s.fbnr = f.fbnr AND PruefOrd = PO96 ; CREATE VIEW GehaltFB (FbNr, FBName, GehSum) AS SELECT f.fbnr, f.name, sum(m.gehalt) FROM MITARBEITER m, FACHBEREICH f WHERE m.fbnr = f.fbnr GROUP BY f.fbnr, f.name; CREATE VIEW GehaltProfFB (FbNr, FBName, GehSum) AS SELECT f.fbnr, f.name, sum(m.gehalt) FROM MITARBEITER m, FACHBEREICH f, PROFESSOR p WHERE m.fbnr = f.fbnr AND m.persnr = p.persnr GROUP BY f.fbnr, f.name; Formulieren Sie für die folgenden Aufgaben jeweils SQL-Anfragen (unter bestmöglichem Einsatz der vordefinierten Views) und geben sie für jede dieser Anfragen an, wie die schrittweise Abbildung auf Basisrelationen durchgeführt wird. Welche Anfragen lassen sich nicht so leicht abbilden? Welchen Zusatzmechanismus muss ein Datenbanksystem bereitstellen, damit alle Anfragen beantwortet werden können. Wie sehen ihre Antworten auf die zuvor gestellten Fragen aus, wenn alle Sichten materialisiert abgespeichert werden. a) Finde für alle Studenten die nach der Prüfungsordung von 1996 studieren die Professoren, die sie unterrichten. b) Welcher Dekan verdient am meisten? c) In welchem Fachbereich verdienen die Professoren zusammen am meisten Geld? d) In welchem Fachbereich verdienen die Mitarbeiter ohne Berücksichtigung der Professorengehälter am meisten Geld? e) Wieviel verdienen die Professoren des Fachbereichs Informatik im Mittel. Seite 9

Lösung: a) Finde für alle Studenten die nach der Prüfungsordung von 1996 studieren die Professoren, die sie unterrichten. SELECT DISTINCT p.name FROM StudFbPO96 s, MITARBEITER m, FACHBEREICH f, PROFESSOR p WHERE s.fbnr = m.fbnr AND m.fbnr = f.fbnr AND m.persnr = p.persnr; wird ersetzt durch: SELECT DISTINCT p.name FROM STUDENT s, FACHBEREICH fneu, MITARBEITER m, FACHBEREICH f, PROFESSOR p WHERE s.fbnr = m.fbnr AND m.fbnr = f.fbnr AND m.persnr = p.persnr AND s.fbnr = fneu.fbnr AND PruefOrd = PO96 ; b) Welcher Dekan verdient am meisten? Es lässt sich keine vordefinierte View sinnvoll einsetzen. SELECT p.persnr FROM MITARBEITER m, PROFESSOR p, FACHBEREICH f WHERE m.persnr = p.persnr AND p.persnr = f.dekan HAVING gehalt = max(gehalt) c) In welchem Fachbereich verdienen die Professoren zusammen am meisten Geld? SELECT gfb.fbnr FROM GehaltProfFB gfb HAVING GehSum = max(gehsum); SELECT f.fbnr, FROM MITARBEITER m, FACHBEREICH f, PROFESSOR p WHERE m.fbnr = f.fbnr AND m.persnr = p.persnr GROUP BY f.fbnr, f.name; HAVING GehSum = max(sum(m.gehalt)); Diese Art der Umformung ist semantisch nicht korrekt, weil sich die Aggregatfunktion (max) auch auf die GROUP-BY Definition bezieht. Eine korrekte Umformung ist: SELECT gfb.fbnr FROM (SELECT f.fbnr, f.name, sum(m.gehalt) FROM MITARBEITER m, FACHBEREICH f WHERE m.fbnr = f.fbnr GROUP BY f.fbnr, f.name) gfb HAVING GehSum = max(gehsum); d) In welchem Fachbereich verdienen die Mitarbeiter ohne Berücksichtigung der Professorengehälter am meisten Geld? SELECT gfb.fbnr FROM GehaltFB gfb, GehaltProfFB gpfb WHERE gfb.fbnr = gpfb.fbnr HAVING (gfb.gehsum - gpfb.gehsum) = max(gfb.gehsum-gpfb.gehsum) Seite 10

SELECT gfb.fbnr FROM MITARBEITER gfbm, FACHBEREICH gfbf MITARBEITER gpfbm, FACHBEREICH gpfbf, PROFESSOR gpfbp WHERE gfbm.fbnr = gfbf.fbnr AND gpfbm.fbnr = gpfbf.fbnr AND gpfbm.persnr = gpfbp.persnr AND gfbf.fbnr = gpfbf.fbnr GROUP BY gfbf.fbnr HAVING (sum(gfbm.gehalt) - sum(gpfbm.gehalt)) = max(sum(gfbm.gehalt) - sum(gpfbm.gehalt)) Eine solche Umformung ist auch hier, aus dem gleichen Grund wie bei c), nicht möglich. Eine korrekte Umformung ist: SELECT gfb.fbnr FROM (SELECT f.fbnr, f.name, sum(m.gehalt) FROM MITARBEITER m, FACHBEREICH f WHERE m.fbnr = f.fbnr GROUP BY f.fbnr, f.name) gfb, (SELECT f.fbnr, f.name, sum(m.gehalt) FROM MITARBEITER m, FACHBEREICH f, PROFESSOR p WHERE m.fbnr = f.fbnr AND m.persnr = p.persnr GROUP BY f.fbnr, f.name) gpfb WHERE gfb.fbnr = gpfb.fbnr HAVING (gfb.gehsum - gpfb.gehsum) = max(gfb.gehsum-gpfb.gehsum) e) Wieviel verdienen die Professoren des Fachbereichs Informatik im Mittel. SELECT avg(gpfb.gehsum) FROM GehaltProfFB gpfb, FACHBEREICH f WHERE gpfb.fbnr = f.fbnr AND f.name = Informatik SELECT avg(sum(gpfbm.gehalt)) FROM MITARBEITER gpfbm, FACHBEREICH gpfbf, PROFESSOR gpfbp, FACHBEREICH f WHERE gpfbm.fbnr = gpfbf.fbnr AND gpfbm.persnr = gpfbp.persnr AND gpfbf.fbnr = f.fbnr AND f.name = Informatik GROUP BY f.fbnr; ist semantisch nicht korrekt. Korrekt wäre hingegen: SELECT avg(gpfb.gehsum) FROM (SELECT f.fbnr, f.name, sum(m.gehalt) FROM MITARBEITER m, FACHBEREICH f, PROFESSOR p WHERE m.fbnr = f.fbnr AND m.persnr = p.persnr GROUP BY f.fbnr, f.name) gpfb, FACHBEREICH f WHERE gpfb.fbnr = f.fbnr AND f.name = Informatik Für c), d), e) lassen sich keine Äquivalenten Umformungen auf Basisrelationen ableiten. Die Datenbank muss intern temporäre Tabellen unterstützen um die Anfragen sematisch korrekt durchführen zu können. Wären die Views materialisiert, müssten keine Werte zwischengespeichert werden. Seite 11