Datenbanken-Praktikum SS2011
Evaluation
Evaluationsergebnisse:
SS11-Datenbanken_P-C.pdf
SS11-Datenbanken_P-D.pdf
Finale
Ich habe heute (4.7.) die Noten fertig gemacht. Bitte schaut nochmal darüber, ich würde sie ansonsten nächsten Sonntag an Hr. Heimrich weitermelden.
Blatt 10
Update 26.06.2011:
a) Abgabe von Blatt 11 ist am Mittwoch 29.6.
Hinweise zu Blatt 11, Aufgabe 2.2.c:
Ein Attribut ist als Schlüsselkandidat zu betrachten, wenn es:
- bei keiner Abhängigkeit auf der linken Seite des Pfeils steht (es also von nichts anderem abhängig ist). Wenn, wie bei Teil c), ein Zirkelbezug besteht,
kann man sich für eines der Attribute entscheiden.
- es in keiner Abhängigkeit auftaucht (z.B. Attribut "G" in Teil c).
b) Abgabe von Blatt 10 ist wegen der offenen Fragen ebenfalls am Mittwoch 29.6.
c) Die ungeklärten Fragen zu Aufgabe 1.6 und 2 sind an Hr. Heimrich geschickt - gerade eben kam eine Antwort rein:
Sie haben Recht, wenn Sie sagen, dass die Tabelle "Hören" unterschiedlich interpretiert wird.
Sprich: bei Aufgabe 1.6 enthält "Hören" nur die im aktuellen Semester belegten Vorlesungen. Bei Aufgabe 2 enthält die Relation die gesamte Historie an bereits besuchten Vorlesungen
d) Aufgabe 11a sollte eigentlich im Zuge der Normalisierungsaufgaben nachgeholt werden. Da das letzten Mittwoch unterging, gibt es für jeden, der 11 b/c abgegeben hatte,
den fehlenden Punkt gratis.
e) Ich habe die aktuellen Punktsummen ausgerechnet - bitte prüft das nach und meldet euch bei mir, wenn etwas nicht stimmt.
Hier ein paar Rückmeldungen von Hr. Heimrich bezüglich "Relationale Algebra":
- Falsche Bedingung auf Seite 4 beim Selektionsbeispiel: ist mittlerweile korrigiert und die neue Version des PDF ist online.
- Blatt 15, "Allgemeiner Verbund": Beispiel "was ermittelt diese Abfrage": es ist korrekt, dass diese Abfrage keinerlei Treffer liefert.
- Operatorbaum (wie im Praktikum zum Beispiele für Umbenennung vorgeführt): eine "Umbenennung" wird als eigener Knoten modelliert, wie an der Tafel skizziert.
- Vorlesungsfolien wurden mit LaTex erstellt, und auch da gibt es nicht alle Operatoren der Relationalen Algebra. Ich selbst
habe kein grafisches Tool für die Darstellung des Ganzen gefunden, d.h. wir müssen bei handschriftlichen Abgaben bleiben.
Es wäre eine Aufgabe für ein "Softwaretechnik Projekt"-Praktikum, ein solches Tool zu erstellen ;-).
Kaum wartet man einen Tag und sucht dann nochmal im Web, findet man dann doch etwas:
Zuerst einmal ein Link, der erklärt, wie man sich die Symbole für ein Word-Dokument zusammentrickst: http://cisnet.baruch.cuny.edu/holowczak/classes/3400/relationalalgebra/#mswordsymbols
Und hier findet sich ein browserbasiertes Tool zum Erstellen von Ausdrücken der relationalen Algebra: http://rat.cs.panam.edu/,
basierend auf einem XML-Schema "Relational Algebra Markup Language (RAML)". Der direkte Link zum Editor: http://rat.cs.panam.edu/edit/1.0/
Leider extrem unkomfortabel zu bedienen: man bastelt sich am Besten den Ausdruck in Papierform und klickt ihn dann zusammen, indem man den Operatorbaum von oben nach unten abarbeitet.
Am Ende kann man sich den Ausdruck als XML speichern und flucht danach tierisch, dass "Laden" noch nicht implementiert ist... Eignet sich also eigentlich nur, um
einen Ausdruck zusammenzubauen, einen Screenshot zu machen und ihn sich an die Wand zu hängen. Und außer einem Wikipedia-Eintrag in einer Liste von XML-Sprachen gibt es auch keine Referenzen auf diese Seite.
SQL-Developer
Ausführen von Procedures im SQLDeveloper
Unsere ganzen bisherigen SQL-Statements konnte man markieren und über den Button "Anweisung ausführen" laufen lassen:
Beim Aufruf einer Procedure ("execute ...") gibt es leider eine Fehlermeldung "ORA-00900 Ungültige SQL-Anweisung":
Lösung: das Statement mit dem Prozeduraufruf muss mittels "Script ausführen" gestartet werden:
Grund scheint zu sein, dass der SQL-Developer die Queries lokal parst und "execute" nicht kennt. Er muss sie ungeparst zum Server schicken, und das geht über
"Script ausführen".
Ausgabe von "dbms_output.put_line"
Die Ausgabe oben genannter Prozedur finden wir auf dem Karteireiter "DBMS-Ausgabe" wieder. Gemeinerweise muss dazu noch der Button "DBMS-Ausgabe aktivieren" gedrückt sein:
Im SQLDeveloper 1.5, der an der FH installiert ist, sieht das so aus:
Im SQLDeveloper 3.0, den ich bereitgestellt habe, muss man sich das Fenster erst über Menü "Ansicht" - "DBMS-Ausgabe" dazuschalten (und es
läßt sich nicht den anderen Karteireitern zufügen):
Hier muss man nach dem Klick auf den Button außerdem die Verbindung wählen, für die der Output angeschaltet werden soll.
Troubleshooting
Wenn beim Anlegen einer Prozedur die Meldung "Warnung: Prozedur wurde mit Kompilierungsfehlern erstellt" kommt,
dann hilft dieser Befehl:
show errors;
Es empfiehlt sich, hier den Namen der nicht compilierten Procedure bzw. Function anzugeben, da man sonst alle im System vorliegenden Compilefehler angezeigt bekommt:
show errors PROCEDURE myProcedure;
show errors FUNCTION myFunction;
Oracle-Installation
Der Installer für die OracleXE-Datenbank + SQLDeveloper 3 (Paket ohne Java-Runtime) ist FH-intern über folgenden Pfad erreichbar: "\\Fileserver\staff\knauf\Oracle"
Hinweis zur Oracle-Installation: da die Oracle beim Rechnerstart hochgefahren wird und außerdem der interne Webserver Port 8080 belegt (den man
eventuell für einen anderen Webserver benötigen könnte), empfehle ich, den Oracle-Dienst auf "Manuell" zu setzen und ihn nur bei Bedarf zu starten.
Hierzu in den "Diensten" diese beiden Dienste suchen:
Beide stoppen und sie danach bearbeiten und den Starttyp auf "Manuell" setzen:
Natürlich muss man sie jetzt nach jedem Rechnerneuboot händisch starten, bevor man mit der Oracle arbeiten kann.
Dies kann man über die Dienste-Verwaltung machen, oder über zwei Startmenüpunkte:
Aufgabe 22
Hier die im Praktikum gezeigten "Cursor"-Beispiele:
Ausgabe der Namen aller Länder in der Datenbank:
CREATE OR REPLACE PROCEDURE LandName is
cursor land is
select name from country;
aktuellesLand varchar(254);
begin
open land;
FETCH land INTO aktuellesLand;
WHILE land%FOUND
LOOP
DBMS_OUTPUT.PUT_LINE(aktuellesLand);
FETCH land INTO aktuellesLand;
END LOOP;
CLOSE land;
end;
execute LandName();
Da wir hier im Resultset nur eine einzige Spalte haben, kann man als Datentyp der Variablen der aktuellen Zeile direkt "varchar(254)" verwenden.
Alternativ hätte man sich auch an den Typ der Spalte "Country.Name" binden können:
aktuellesLand country.name%TYPE;
Ausgabe von Kürzel und Namen aller Länder in der Datenbank:
CREATE OR REPLACE PROCEDURE LandCodeName is
cursor land is
select name, code from country;
aktuellesLand land%ROWTYPE;
begin
open land;
FETCH land INTO aktuellesLand;
WHILE land%FOUND
LOOP
DBMS_OUTPUT.PUT_LINE(aktuellesland.code || ' - ' || aktuellesLand.name);
FETCH land INTO aktuellesLand;
END LOOP;
CLOSE land;
end;
execute LandCodeName();
Besonderheit ist, dass die Variable "aktuellesLand" jetzt alle Felder des Cursors "land" enthält, d.h. vom gleichen Typ ist wie eine Zeile des Cursor-Resultsets.
Ausgabe von Kürzel und Namen aller Länder sowie der Anzahl ihrer Städte (Aufgabe 19.1):
CREATE OR REPLACE PROCEDURE LandMitStaedten is
cursor land is
select name, code from country;
aktuellesLand land%ROWTYPE;
anzahlStaedte number;
begin
open land;
FETCH land INTO aktuellesLand;
WHILE land%FOUND
LOOP
select count(*) into anzahlstaedte from city where country = aktuellesland.code;
DBMS_OUTPUT.PUT_LINE(aktuellesland.code || ' - ' || aktuellesLand.name || ', Städte: ' || anzahlstaedte);
FETCH land INTO aktuellesLand;
END LOOP;
CLOSE land;
end;
execute LandMitStaedten();
In Erweiterung des letzten Beispiels wird hier pro Land ein Select ausgeführt, dass alle Städte zurückgibt.
Da dieses Select nur eine einzige Zeile zurückliefert, können wir es direkt, also ohne Cursor, verwenden. Hätten wir mehr als eine Zeile
in der Ergebnismenge, bräuchten wir einen Cursor.
Ausgabe von Kürzel und Namen aller Länder sowie des Prozentsatzes von Einwohnern in Städten mit mehr als 500.000 Einwohnern (Aufgabe 19.7):
CREATE OR REPLACE PROCEDURE LandMitStaedten500000 is
cursor land is
select name, code, population from country;
cursor staedte(countrycode varchar) is
select name, population from city where country = countrycode;
aktuellesLand land%ROWTYPE;
aktuelleStadt staedte%ROWTYPE;
population500000 number;
begin
open land;
FETCH land INTO aktuellesLand;
WHILE land%FOUND
LOOP
population500000 := 0;
open staedte (aktuellesLand.code);
FETCH staedte INTO aktuelleStadt;
WHILE staedte%FOUND
LOOP
if aktuellestadt.population > 500000 then
population500000 := aktuellestadt.population;
end if;
FETCH staedte INTO aktuelleStadt;
END LOOP;
DBMS_OUTPUT.PUT_LINE(aktuellesland.code || ' - ' || aktuellesLand.name || ', Bevölkerung in Großstädten: ' || (population500000 / aktuellesland.population) * 100);
close staedte;
FETCH land INTO aktuellesLand;
END LOOP;
CLOSE land;
end;
execute LandMitStaedten500000();
Pro Land (als pro Schritt im "land"-Cursor) wird ein Cursor "staedte" durchlaufen. Dieser liefert alle Städte des Landes zurück. Pro Stadt wird geprüft,
ob sie mehr als 500.000 Einwohner hat. Ist dies der Fall, wird eine Summe von Großstadtbewohnern hochgezählt. In der Land wird der Prozentwert berechnet.
Anmerkung: Dezimalzahl formatieren:
Um die Prozentzahl aus dem letzten Beispiel mit einer vernünftigen Anzahl von Nachkommastellen auszugeben, kann folgendes Statement verwendet werden:
TO_CHAR ( (population500000 / aktuellesland.population) * 100, '99.99')
Mehr Infos hier: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34570
Troubleshooting
Falls ihr z.B. eine Prozedur gebaut habt, die eine Endlosschleife enthält (UND auf eurem Privat-PC arbeitet - an der FH geht das natürlich nicht so):
- Mit dem Oracle verbinden: http://127.0.0.1:8080/apex und anmelden als User "SYSTEM"
- Auf "Administration" klicken:
- Auf "Überwachen" klicken:
- Auf "Sessions" hauen:
- Man sieht eine Liste der Sessions. Hier die vermutlich schuldige Session heraussuchen und auf den Link der Spalte "SID" klicken:
- In der Detailansicht (man sieht auch das gerade laufende SQL-Statement) auf "Session abbrechen" klicken und danach bestätigen:
Aufgabe 19
Ein paar Hinweise, damit ihr eure Lösungen auf Korrektheit prüfen könnt (ich hoffe ich habe keine Fehler in diesen Ergebnissen - wenn doch: wer mir einen Fehler als
erstes beweist, bekommt einen Bonuspunkt ;-)):
- Teil 3: es gibt fünf Länder mit mehr als 100 Städten (Länderkürzel: R, USA, TJ, GB, BR)
- Teil 4: es sollten 152 Organisationen herauskommen. "ABEDA" (Arab Bank for Economic Development in Africa) z.B. hat 17 Mitgliedsländer mit 243.646.211 Einwohnern.
Und die "UPU" (Universal Postal Union) hat 186 Mitgliedsländer mit 5.723.978.225 Einwohnern
- Teil 5: 71 Religionen, es gibt z.B. Muslim = 990.514.246,93, Lutheran = 2.041.874,47, Shinto Buddhist = 105.377.750,52
- Teil 6: 8 Treffer: Kingston, Springfield, Cordoba, Leon, Alexandria, Merida, La Paz, Trujillo
- Teil 7: es gibt 95 Länder mit Städten mit mehr als 500.000 Einwohnern.
Einige Beispiele: Italy = 13,67% in 6 Städten, China = 8,46% in 60 Städten, Germany = 15,94% in 13 Städten
Aufgabe 18
Musterlösung zu Aufgabe 18b:
Zuerst einmal mein Vorschlag aus dem Praktikum:
select m.nachname, m.vorname, p.projekt from projekt p, mitarbeiter m where p.nachname = m.nachname and p.vorname = m.vorname
union
(select p.nachname, p.vorname, null from projekt p
minus
(
select m.nachname, m.vorname, null from projekt p, mitarbeiter m where p.nachname = m.nachname and p.vorname = m.vorname
)
);
Alternativlösung (Quelle: http://en.wikipedia.org/wiki/Join_(SQL)#Alternatives):
SELECT m.nachname, m.vorname,
(
SELECT p.Projekt
FROM projekt p
WHERE p.nachname = m.nachname and p.vorname = m.vorname
) AS Projekt
FROM mitarbeiter m;
Aufgabe 16
Musterlösung zu Aufgabe 16 h:
Lösung mit "group by/having":
select city.Name, country.Name from city, country where city.country = country.code
and city.Name in (select cityInner.Name from City cityInner group by cityInner.Name having count(*) > 1)
order by city.name, country.name;
Lösung ohne "group by/having":
Zuerst eine vereinfachte Form der Query, die nur die Städte zurückliefert. Es werden alle Städte mit gleichem Namen,
aber abweichendem Primärschlüssel (name, country, province) gesucht.
Die zweite Variante der Query holt sich noch das Country dazu.
select * from city where name in (select name from city cityInner where cityInner.Name = city.Name
and (cityInner.country <> city.country or cityInner.province <> city.province))
order by city.name;
select city.Name, country.Name from city, country where city.country = country.code and
city.name in (select name from city cityInner where cityInner.Name = city.Name
and (cityInner.country <> city.country or cityInner.province <> city.province))
order by city.name, country.name;
Musterlösung zu Aufgabe 16 h:
Lösung mit "group by/having":
select city.Name, country.Name from City, Country where city.country = country.code
group by city.Name, country.Name having count(*) > 1
order by city.name, country.name;
Lösung ohne "group by/having":
select distinct city.Name, country.Name from city, country where city.country = country.code and
city.name in (select name from city cityInner where cityInner.Name = city.Name
and cityInner.country = city.country and cityInner.province <> city.province)
order by city.name, country.name;
Aufgabe 12-14
Oracle-Info: VARCHAR vs. VARCHAR2:
Siehe http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/sql_elements001.htm#sthref77:
Oracle warnt explizit davor, den Datentyp VARCHAR zu verwenden, da er im Moment zwar mit VARCHAR2 identisch ist, aber in einer zukünftigen Version eine abweichende Bedeutung
bekommen könnte (was auch immer das für uns heißt ;-))
Die Abgabe sollte so aussehen:
- Alle Scripte in elektronischer Form, so dass ich sie alle testen kann (das gilt auch für alle zukünftigen SQL-Aufgaben).
- Aufgabe 12: zu jedem der Einzelschritte a.I bis a.X und b.I bis b.X ein kleines SQL-Script für den Testfall (dies könnt ihr als kleine Einzeldateien
oder als großes Script abgeben). Zu jedem der Einzelschritte außerdem die entsprechende Oracle-Fehlermeldung sowie eine Erklärung abgeben.
Bei Fehlermeldungen bitte beachten: es gibt auch "falsche Fehler", z.B. wegen Syntax im SQL - diese sind hier nicht das gewünschte Ergebnis ;-).
- Aufgabe 12: ich gehe davon aus, dass alle Spalten "not null" deklariert sind (auch wenn man annehmen könnte, dass in 12.a alle Spalten NULL-Werte zulassen könnten,
da hier keine datenbankseitigen Prüfungen implementiert sind - in 12.b ist auf jeden Fall alles "not null").
- Aufgabe 12.a.IX, 12.a.X, 12.b.IX und 12.b.X: das Statement "desc TABLENAME" auf alle Tabellen ausführen und die entsprechenden Ergebnisse begründen (falls
das Löschen der Tabelle nicht sowieso von der Datenbank mit einer Fehlermeldung quittiert wird).
- Aufgabe 14: den einen Punkt bekommt ihr alle ohne weitere Leistung - ihr braucht die Mondial-Datenbank sowieso lauffähig
Werft ab und zu einen Blick auf diese Seite, eventuell fallen mir noch mehr Sonderwünsche ein.
Praktikum am 20.4.
Aus Zeitgründen muss die zweite Stunde ab 17:30 diesmal ausfallen (falls überhaupt noch jemand kommt ;-). Das Praktikum um 16 Uhr findet wie gewohnt statt!
Aufgabe 5-8
Eine Übersicht über die Syntaxelemente eines ER-Diagramms gemäß Chen-Notation: http://de.wikipedia.org/wiki/Chen-Notation
Man beachte, dass es gemäß dieser Definition kein "m:n" gibt, da "m" (="must") ein Notatationselement der modifizierten Chen-Notation ist, "n" aber zur Basis-Chen-Notation gehört
Und eine weitere Erweiterung: die "Min-Max-Notation": http://de.wikipedia.org/wiki/Min-Max-Notation
Hr. Heimrichs Kommentar zur Frage "welche dieser Notationen wird in der Vorlesung verwendet":
[Es gibt] nicht "DEN Standard", den ich in die Vorlesung übernommen habe. Das Problem ist, dass sich diese Notationen historisch entwickelt haben und jede
ihre Vor- und Nachteile hat. Im wesentlichen ist es aber die erweiterte Notation von Chen und die Min:Max-Notation. Diese habe ich dazu genommen, weil die klassischen m:n-Beziehungen manchmal zu ungenau sind.
Ein Beispiel für eine ternäre Relation: http://www.luo-darmstadt.de/wiki/index.php?title=Spezielle_Beziehungen
Tool für ER-Diagramme: "DIA": http://projects.gnome.org/dia/
Download des Installers für Windows: http://sourceforge.net/projects/dia-installer/files/dia-win32-installer/
Aufgabe 1
3-Ebenen-Konzept: mehr Details: http://www.info-wsf.de/index.php/Das_ANSI-Architekturmodell_(3-Schichten-Architektur)
Stand 07.07.2011
Historie:
30.03.2011: Erstellt
01.04.2011: Nachtrag zweier Bewertungen von Aufgabe 1
10.04.2011: Bewertung Blatt 2
17.04.2011: Blatt 2, Aufgabe 7+8
18.04.2011: Ausfall Gruppe 2 20.4.
20.04.2011: Oracle-Hinweise und Wünsche zu Blatt 4
22.04.2011: Bewertung Blatt 3
27.04.2011: Oracle-Start/Stopp-Hinweis überarbeitet, VARCHAR/VARCHAR2-Info
02.05.2011: Erste Bewertungen für Blatt 4
08.05.2011: Nachbewertung 762805, finale Bewertung Blatt 4
09.05.2011: Hr. Heimrichs Antwort zur Frage "welche Notation für Kardinalitäten?"
10.05.2011: Vorabbewertung Blatt 5
15.05.2011: Bewertung Blatt 5, Musterlösung Aufgabe 16 h/i
17.05.2011: Erste Vorabbewertung Blatt 6
22.05.2011: Bewertung Blatt 6, Musterlösung Aufgabe 18b, Hinweise zu 19
25.05.2011: Hinweise zu Procedures/Functions
29.05.2011: Update der Bewertung Blatt 4 von 465541, Update der Bewertung Blatt 6 von 867458, Bewertung Blatt 7
30.05.2011: Nachbewertung Blatt 7 von 862806
31.05.2011: Nachbewertung Blatt 7 von 867458
01.06.2011: Cursor-Beispiele und Infos zum Session-Abbruch
05.06.2011: Erster Teil der Bewertungen Blatt 8
06.06.2011: Nachbewertung Blatt 8 von 961720, 854968
16.06.2011: Nachbewertung Blatt 8 von 366326, 567235; Bewertung Blatt 9; Evaluation; Hinweise zu Blatt 10
17.06.2011: Nachbewertung Aufgabe 23 von 862806, erste brauchbare Infos zu Tools für relationale Algebra
26.06.2011: Hinweise zu Blatt 10 und 11, aktuelle Punktstand-Summen
27.06.2011: Mehr Hinweise zu Blatt 11, Gnadennachbewertung 662600
29.06.2011: Klärung Blatt 10, Aufgabe 1.6/2
27.06.2011: Gnadennachbewertung 265191 (Blatt5-9)
03.07.2011: Bewertung Blatt 10
04.07.2011: Bewertung Blatt 11
05.07.2011: Nachbewertung Blatt 8 von 662600
07.07.2011: Gruppenwechselpunkte von 465567