Skip to Content

TU Wien Fakultät für Informatik DBAI Database and Artificial Intelligence Group
Top-level Navigation: Current-level Navigation:

Path: DBAI > Education > Datenbanksysteme > Übung > Beispiel 2

Tools: Drucken


Datenbanksysteme (VU 4.0, 184.686)
Übungsteil, WS 2015/2016

Beispiel 2

Große Teile von Beispiel 2 basieren auf der im Zuge von Beispiel 1 erstellten Datenbank. Sie können entweder die Musterlösung als Basis für diese Aufgabe verwenden, oder ihre eigene Lösung weiterverwenden. Die Musterlösung wird mit Ablauf der Abgabegespräche zu Beispiel 1 auf der Übungsseite der Lehrveranstaltung veröffentlicht.

Wenn Sie ihre eigene Lösung weiterverwenden wollen kann es passieren, dass aufgrund anderer Namensgebung (für Tabellen und/oder Attribute) kleine Adaptierungen vorgenommen werden müssen. Konkret sind einige Codeblöcke im Java-Teil vorgegeben, welche auf die Bezeichnungen der Musterlösung abgestimmt sind. Unter Umständen müssen Sie diese anpassen, oder Sie passen ihre Lösung aus Beispiel 1 daran an.

Grundgerüst

Als Grundgerüst finden Sie auf der Übungsseite ein ZIP-Archiv mit einer grundlegenden Projektstruktur die Sie als Vorlage für diese Übung nutzen müssen. Weiters wird Ihnen in diesem Gerüst ein ant-Skript zur Verfügung gestellt (build.xml), um das Testen und die Abgabe der Übung zu vereinfachen: dbs-template-r1.zip (Rev. 1, inkl. Musterlösung).

Beachten Sie:

Teil 1 - PL/pgSQL

Die folgenden Aufgabenstellungen basieren auf der Datenbank, welche Sie für Beispiel 1 des Übungsteils zu erstellen hatten. Sie können entweder auf Ihrer Datenbank weiterarbeiten, oder die Musterlösung des ersten Beispiels verwenden. Diese steht nach den Abgabegesprächen zu Beispiel 1 auf der LVA-Homepage zum Download bereit. Stellen Sie sicher, dass Sie in Ihrer Abgabe die Create-, Insert- und Drop-Befehle jener Datenbank bereitstellen, auf der Sie arbeiten. Ersetzen Sie dazu im Verzeichnis resources in der Vorlage die Dateien.

Beachten Sie, dass die Daten, mit denen Sie testen, der Spezifikation entsprechen sollen (d.h. Berücksichtigung der Kardinalitäten etc.). Sie müssen keine Fälle berücksichtigen, die der Spezifikation widersprechen.

PL/pgSQL Funktionen und Prozeduren:

  1. Schreiben Sie eine Funktion create_rechung().
    Die Funktion soll folgende Tätigkeiten durchführen:
    1. Mit Hilfe einer Sequenz eine neue Rechnungsnummer generieren.
    2. Eine neue Rechnung mit aktuellem Datum in der Tabelle rechnung anlegen.
    3. Die generierte Rechnungsnummer mittels RETURN ausgeben.
  2. Schreiben Sie eine Prozedur create_rpos(rnr,anr,apnr).
    Die Prozedur soll für die Rechnung rnr eine Rechnungsposition anlegen die zur Auftragsposition mit dem Key (Anr,APnr) gehört. Dazu führen Sie folgende Tätigkeiten durch:
    1. Überprüfen Sie, ob es zur Auftragsposition (ANr,APNr) entweder eine Leistungsposition oder eine Sonstige Position gibt.
    2. Falls es noch keine Rechnungsposition für diese Rechnung gibt, setzen Sie RPNr mit 1 fest. Ansonsten lesen Sie die höchste RPNr für diese Rechnung aus und erhöhen Sie sie um 1.
    3. Der Text der Rechnungsposition entspricht der Beschreibung der Sonstigen Position oder der Bezeichnung der in der Leistungsposition referenzierten Leistung. Überlegen Sie sich eine einzelne Query (benötigt UNION), die Ihnen diese Information in einer Variable speichert.
    4. Den Wert der Rechnungsposition können Sie mit Hilfe der in der ersten Übung erstellen Funktion f_calc_apos() berechnen lassen.
    5. Fügen Sie nun die erzeugten Daten in die Tabelle Rechnungsposition ein.
  3. Schreiben Sie einige Statements, die ihre Prozeduren und Funktionen auf die korrekte Vorgehensweise testen.

Teil 2 - Java (Concurrency)

Beachten Sie, dass die vorgegebenen Codezeilen, die durch einen Kommentarblock (“Vorgegebener Codeteil”) markiert sind und durch eine Kommentarzeile aus Hashtags (#) geschlossen werden, nicht verändert werden dürfen.

Das erste Szenario (Szenario1.java) ist so angelegt, dass es eine von Ihnen zu ergänzende Transaktion gibt und eine bereits existierende Transaktion, die Ihnen von uns zur Verfügung gestellt wird.

Sie müssen hierbei die Methode runTransactionA() vervollständigen, indem sie den in der Vorlage bereitgestellten Code ergänzen. Die bereitgestellte Methode runTransactionB() dient zur Überprüfung der Funktionalität und erzeugt bei Wahl des falschen Isolation-Levels ein Fehlverhalten.

Die Parameter für Szenario 1 sind:

  1. “a” oder “b” für die Wahl der jeweiligen Transaktion
  2. Servername
  3. Port-Nummer
  4. Datenbank-Name
  5. Username (optional)
  6. Passwort (optional)

Zum vereinfachten Testen haben wir Ihnen in diesem Semester auch ein ant-Skript zur Verfügung gestellt. Wenn Sie Ihre Verbindungs- und Benutzerdaten in diesem Skript hinterlegen, müssen Sie nur mehr die folgenden Aufrufe benutzen, um die Programme zu starten:

  1. ant run-szenario1-a (Für Ihre eigene Implementierung von Szenario 1)
  2. ant run-szenario1-b (Für die von uns bereitgestellte Transaktion zu Szenario 1)

Für einen Test öffnen Sie am besten zwei Konsolenfenster. Im ersten Fenster rufen Sie zuerst Ihre eigene Implementierung auf (also z.B. mittels des Befehls “ant run-szenario1-a”) und im zweiten Fenster die von uns bereitgestellte zugehörige Transaktion (z.B. “ant run-szenario1-b”). Sie sollten nun zwei Konsolenfenster sehen, die beide auf eine Eingabe warten. Wenn Sie im Fenster mit der Transaktion A die Eingabetaste drücken, startet der von Ihnen programmierte Ablauf, welcher die erste Ausgabe anzeigt. Transaktion B starten Sie ebenfalls mit der Eingabetaste. Transaktion B verändert nun den Datenbestand in der Datenbank. Wenn Sie nun wieder im anderen Konsolenfenster mit der Transaktion A die Enter-Taste betätigen, sollte im Erfolgsfall die korrekte zweite Ausgabe Ihres Programms erscheinen. Überprüfen Sie nun sorgfältig, ob sich Ihr Programm auch wirklich nach der Spezifikation verhält und keine unerwünschten Ergebnisse durch die Transaktion B entstehen. Durch eine andere Reihenfolge beim Drücken der Enter-Taste in den verschiedenen Programmen können Sie natürlich auch andere Ablaufmuster und Verschachtelungen der Transaktionen simulieren und testen.

Beachten Sie, dass Sie anschließend beim Abgabegespräch Ihr Vorgehen bei der Erstellung und auch die Funktionsweise des Programms erklären sollen. (Insbesondere auch die Frage, warum Sie der Meinung sind, dass Ihr Programm die Aufgabenstellung optimal erfüllt!)

Szenario 1:

Folgende Zahlenwerte sollen in Transaktion A aus der Datenbank ermittelt werden:

  1. Die Anzahl der Aufträge pro Kunde und
  2. die Gesamtanzahl an Aufträgen.

Setzen Sie das Transaktionslevel so, dass die Zahlenwerte übereinstimmen. Beachten Sie diese Anforderungen und den möglichen Zusammenhang der beiden Abfragen. Für das Abgabegespräch überlegen Sie sich folgendes:

  1. Welches Isolation-Level reicht hierfür aus?
  2. Welcher Effekt tritt auf, wenn ein zu niedriges Transaktionslevel ausgewählt werden würde?

Ermitteln Sie die geforderten Informationen durch geeignete SELECT-Befehle in den bereitgestellten Codeblöcken der Transaktion A in Szenario 1. Mit der zur Verfügung gestellten Transaktion B können Sie verschiedenste Verschachtelungen der einzelnen Befehle durchspielen und so gewollte, oder aber auch ungewollte Effekte des gewählten Isolation-Levels sehen.

Hinweis:

Im Rahmen des Abgabegesprächs wird nicht nur die Korrektheit der Lösungen, sondern vor allem auch das Verständnis überprüft. Sie sollten in der Lage sein zu erklären wie sich die Wahl des Isolation-Levels auf das Programmverhalten auswirkt. Zudem ist ein gewisses Basiswissen im Bereich Concurrency gefordert. Dazu zählt zum Beispiel das Verständnis von Transaktionen (sprich z.B. ACID), die Charakteristika von Isolation-Levels und welche Anomalien die einzelnen Isolation-Levels beheben (z.B. Dirty Read).

Teil 3: Java (PL/pgSQL)

In der zweiten und dritten Datei (Szenario2.java, Szenario3.java) sollen Sie die Anforderungen entsprechend der Angabe implementieren. Sie können diese Programme entweder mittels der Kommandozeilen-Argumente, oder wiederum direkt mittels des ant-Skripts (“ant run-szenario2”, “ant run-szenario3”) starten.

Die Argumente für den Aufruf der nächsten beiden Szenarien sind:

  1. Servername
  2. Port-Nummer
  3. Datenbank-Name
  4. Username (optional)
  5. Passwort (optional)

Auch hier müssen Sie beim Abgabegespräch in der Lage sein, detaillierte Fragen zum Verständnis der Anwendung und Ihres Vorgehens bei der Implementierung zu beantworten.

Szenario 2: (Kundendaten archivieren)

Es sollen die nicht mehr aktuellen Einträge der Tabelle Kundendaten archiviert werden. Dazu implementieren Sie folgendes Verhalten:

  1. Erstellen Sie in der Methode prepareStatement() zwei Prepared Statements. Das Prepared Statement pstmt_kundendaten soll mit Hilfe der in Beispiel 1 erstellen View AktKundendaten die aktuellen Kundendaten einer übergebenen knr ausgeben. Das Prepared Statement pstmt_kunde soll den Namen des Kunden einer übergebenen knr ausgeben.
  2. In der Methode run() durchlaufen Sie alle Kundendaten mit Hilfe eines Updatable Statements. Verwenden Sie das Prepared Statement pstmt_kundendaten um zu überprüfen, ob die Kundendaten die aktuellen sind. Falls sie es nicht sind, geben Sie ein INSERT Statement aus, damit die archivierten Kundendaten später wieder eingefügt werden können und löschen Sie die nicht aktuellen Kundendaten aus der Tabelle (mittels der deleteRow()-Methode des ResultSet).
  3. Geben Sie zusätzlich eine Statistik des Archivierungsprozess aus. Geben Sie hierfür die Nr und den Namen des Kunden, und die Anzahl der archivierten Einträge dieses Kunden aus. Verwenden Sie für den Namen das angelegte PreparedStatement pstmt_kunde. Geben Sie auch die Gesamtanzahl an archivierten Einträgen aus.

Ihre Implementierung soll folgende Ausgabe erzeugen:
INSERT INTO Kundendaten VALUES (1,'2014-10-11','Hauptstraße 4',5);
INSERT INTO Kundendaten VALUES (2,'2014-10-18','Weinweg 3/a',10);
INSERT INTO Kundendaten VALUES (3,'2014-11-28','Am Entenweg 4',5);
INSERT INTO Kundendaten VALUES (4,'2015-05-17','Axerweg 56',10);
INSERT INTO Kundendaten VALUES (4,'2014-10-17','Markusgasse 77',10);
INSERT INTO Kundendaten VALUES (5,'2010-01-28','Hauptstraße 77',20);

Anzahl der archivierten Eintraege fuer [1] Max Mustermann: 1
Anzahl der archivierten Eintraege fuer [2] Werner Gruber: 1
Anzahl der archivierten Eintraege fuer [3] Ines Bach: 1
Anzahl der archivierten Eintraege fuer [4] Martin Huber: 2
Anzahl der archivierten Eintraege fuer [5] Petra Grasich: 1
--------------------------------------------------
Gesamtanzahl an archivierten Eintraegen: 6

Szenario 3: (Rechnungen ausgeben)

Es sollen die in der Datenbank gespeicherten Rechnungen ausgeben werden. Dazu implementieren Sie folgendes Verhalten:

  1. Erstellen Sie in der Methode prepareStatement() zwei Prepared Statements. Das Prepared Statement pstmt_rpos soll die Rechnungspositionen einer übergebenen rnr ausgeben. Das Prepared Statement pstmt_kunde soll knr, name und aktuelle Anschrift des Kunden einer Rechnung ausgeben (Hinweis: Dafür müssen Sie zuerst den Auftrag ermitteln der zu dieser Rechnung gehört).
  2. In der Methode run() durchlaufen Sie alle Rechnungen. Verwenden Sie das PreparedStatement pstmt_kunde um einen Rechnungskopf zu drucken. Verwenden Sie dann das Prepared Statement pstmt_rpos um die Rechnungspositionen auszugeben. Zum Abschluss zeigen Sie den Gesamtbetrag der Rechnung an (Summe der Rechnungspositionen).

Ihre Implementierung soll folgende Ausgabe erzeugen:
-------------------------------------------------------------
Rechnung #3
-------------------------------------------------------------
Werner Gruber
Patentstraße 56

 Pos  |                  Text                    |  Betrag
------+------------------------------------------+-----------
    1 | Artikel 3 - Leistung 4                   |     105,30
    2 | SonstigePosition 1                       |      81,00
-------------------------------------------------+-----------
                                        Gesamt : |     186,30
-------------------------------------------------------------

Abgabe

Führen Sie folgenden Befehl aus, um ein abgabefertiges Archiv dbs-exercise3-ws15.zip zu erzeugen:

Diese ZIP-Datei ist bis spätestens 29.11.2015, um 23:59 Uhr in TUWEL abzugeben. Beachten Sie, dass stets die zuletzt hochgeladene Version Ihrer Lösung gewertet wird.

Führen Sie keine Änderung an der “Testumgebung” aus Teil 2 (DBConnector.java, Main-Methoden, etc.) durch, da ansonsten ihre Abgabe im Rahmen des Abgabegesprächs möglicherweise nicht ausgeführt werden kann.

Abgabegespräche

Die Verteilung der Punkte erfolgt nach folgendem Schlüssel:

  1. Datei plpgsql.sql: 3
  2. Datei Szenario1.java: 4
  3. Datei Szenario2.java: 4
  4. Datei Szenario3.java: 4

Im Rahmen des Kontrollgespräches wird nicht nur die Korrektheit, sondern vor allem das Verständnis der Konzepte überprüft. Durch die Übung sollen sowohl Ihre praktische Problemlösungskompetenz, als auch das theoretische Wissen über Datenbanksysteme gefördert werden. Sie müssen daher in der Lage sein, nicht nur Ihre Beispiele zu erklären, sondern auch zeigen, dass Sie die bisher in der Vorlesung behandelte Theorie zu diesen Beispielen ausreichend verstanden haben. Dies soll Ihnen die Vorbereitung auf die Prüfung erleichtern. So können Sie Ihr Wissen während der Abgabegespräche selbst testen und gegebenenfalls vertiefen.

Die volle Punktezahl gibt es nur, wenn die Beispiele korrekt gelöst wurden und die Lösung einwandfrei erklärt werden kann. Nicht selbstständig gelöste Abgaben werden mit 0 Punkten bewertet!

Erscheinen Sie in Ihrem eigenen Interesse pünktlich zum Abgabegespräch, da andernfalls nicht garantiert werden kann, dass Ihre gesamte Lösung in der verbleibenden Zeit beurteilt werden kann.

Zum Abgabgegespräch bringen Sie unbedingt Ihren Studentenausweis mit, da ansonsten eine Abgabe ausnahmslos nicht möglich ist.

Hinweise zur Verwendung von psql

Folgende Befehle können für Ihre Arbeit mit der interaktiven SQL-Shell psql von PostgreSQL hilfreich sein:

  1. \?: Listet alle psql-internen Befehle samt Erklärung auf.
  2. \i <dateiname>: Führt das Skript <dateiname> aus. Beispiel: \i create.sql
  3. \o <dateiname>: Lenkt die Ausgabe in eine Datei mit dem Namen <dateiname> um. Lässt man den Parameter <dateiname> weg, so wird dieses Verhalten wieder abgestellt. Beispiel: \o index.txt

Home / Kontakt / Webmaster / Offenlegung gemäß § 25 Mediengesetz: Inhaber der Website ist das Institut für Logic and Computation an der Technischen Universität Wien, 1040 Wien. Die TU Wien distanziert sich von den Inhalten aller extern gelinkten Seiten und übernimmt diesbezüglich keine Haftung. Disclaimer / Datenschutzerklärung