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:
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":


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:
Anweisung ausführen

Beim Aufruf einer Procedure ("execute ...") gibt es leider eine Fehlermeldung "ORA-00900 Ungültige SQL-Anweisung":
ORA-00900

Lösung: das Statement mit dem Prozeduraufruf muss mittels "Script ausführen" gestartet werden:
Script ausführen
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:
DBMS-Ausgabe

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):
DBMS-Ausgabe
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:
Oracle-Dienste
Beide stoppen und sie danach bearbeiten und den Starttyp auf "Manuell" setzen:
Oracle-Dienste (manuell)
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:
Oracle starten/stoppen


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):

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 ;-)):

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:
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