Datenbanken-Praktikum SS2013

Danke für eure Evaluation: SS13-Datenbanken_P-D.pdf (nur Gruppe D, für Gruppe E waren zuwenig Formulare abgegeben worden)

Bewertungen

Da meine Benotungsweise härter ist als in den Gruppen von Hr. Heimrich, werden am Ende vermutlich 10% auf die Punktzahl aufgerechnet.

Das Bild der handgemalten Wolke in der nächsten Tabelle heißt "Abgabe ist per Mail erfolgt" - Maus über das Bildchen bewegen, um meine Anmerkungen als Tooltip zu sehen.




Aus der Stunde vom 26.6.

Beispieltrigger für "Mitarbeiter darf maximal fünf Fähigkeiten haben":
create or replace trigger MaxFaehigkeitenPruefen before insert on MitarbeiterFaehigkeit for each row
declare Mitarbeiterfaehigkeiten number;
begin
  dbms_output.put_line ('Insert in MitarbeiterFaehigkeit mit Mitarbeiternummer = ' || :new.mitarbeiternummer || ', Fähigkeit = ' ||
    :new.faehigkeitnummer);
  select count (*) into Mitarbeiterfaehigkeiten from  MITARBEITERFAEHIGKEIT where mitarbeiternummer = :new.mitarbeiternummer;
  if (Mitarbeiterfaehigkeiten = 5) then
    raise_application_error (-20001, 'Hat schon 5 Fähigkeiten');
  end if;
end;


Aus der Stunde vom 19.6.

Folgende Prozedur baut das Select-Statement aus Blatt 6d nach (Ausgabe des Anteils der Fläche an Europa pro Land), und erweitert es für beliebige Kontinente:
CREATE OR REPLACE PROCEDURE Blatt6d (kontinent CONTINENT.NAME%TYPE) IS

CURSOR countries_on_continent IS
  SELECT * FROM Country, encompasses WHERE encompasses.continent = kontinent and country.code = encompasses.country; 
current_country countries_on_continent%ROWTYPE;

--Datentyp der Variablen "groesse_europa" könnte man aus der Tabellenspalte übernehmen.
--groesse_kontinent CONTINENT.AREA%TYPE;
groesse_kontinent NUMBER;
Begin
  
--Zuerst Fläche von Europe ermitteln:
select continent.area into groesse_kontinent from continent where name = kontinent;
DBMS_OUTPUT.PUT_LINE('Größe von ' || kontinent || ': ' || groesse_kontinent);

OPEN countries_on_continent;

FETCH countries_on_continent INTO current_country;
WHILE countries_on_continent%FOUND LOOP
  DBMS_OUTPUT.PUT_LINE('Country: '|| current_country.code || ' - ' || current_country.name || 
     ', Anteil an ' || kontinent || ': ' || (current_country.Area*(current_country.Percentage/100)/ groesse_kontinent) );
  FETCH countries_on_continent INTO current_country;
END LOOP;
CLOSE countries_on_continent; 

end;

Ausführen:
execute Blatt6d ('Asia');
Falls Compilefehler kommen:
show errors PROCEDURE Blatt6d;


Blatt 6:

Musterlösung: blatt6.sql


Blatt 5: SQL-Tipps

Bitte achtet beim Anlegen von Primary Keys und Foreign Keys darauf, dass diese immer Namen haben.
Beispiel:
CREATE TABLE BESTELLER
(
  TELEFON NUMBER not null, 
  ORT VARCHAR(10) not null, 
  NAME VARCHAR(10) not null,
  constraint BESTELLER_PK primary key (TELEFON)
);

create table ANRUF
(
  NUMMER NUMBER not null,
  TELEFON NUMBER not null,
  DATUM char(10) not null,
  UHRZEIT char(5) not null,
  constraint ANRUF_PK primary key (NUMMER),
  constraint ANRUF_FK1 foreign key (TELEFON) references BESTELLER(TELEFON)
);
Dadurch kann man später die Constraints nämlich per SQL manipulieren. Beispiel: in der Tabelle "Anruf" soll der Foreign Key auf "delete cascade" umgestellt werden. Dazu muss zuerst der alte Foreign Key gelöscht werden:
alter table ANRUF drop constraint  ANRUF_FK1;
alter table ANRUF add constraint ANRUF_FK1 foreign key (TELEFON) references BESTELLER(TELEFON) on delete cascade;

Die Namensvergabe sollte auch für Unique-Constraints und Check-Constraints angewendet werden. Beispiel aus einer Oracle-Doku (http://www.remote-dba.cc/t_garmany_easysql_check_constraint_triggers.htm):
create table editor
(
  editor_key             varchar2(9) not null,
  editor_last_name       varchar2(40),
  editor_first_name      varchar2(30) not null,
  editor_hire_date       date,
  editor_active          char(1) 
  constraint active_ck check (editor_active in ('Y','N')),
  constraint ed_name_un unique (editor_first_name,editor_last_name),
  constraint editor_pk primary key (editor_key)
);
Die verkürzte Variante aus der Vorlesung, wo die Check-Constraint direkt hinter dem Namen der zu prüfenden Spalte notiert wird, erlaubt ebenfalls die Angabe eines Constraint-Namens. Modifiziertes Beispiel aus "Vorlesung6.pdf", Seite 10:
CREATE TABLE Verkaeufer
(
  VNR NUMBER constraint VNrGroesser1000 CHECK(VNR >= 1000),
  Vname VARCHAR(12) NOT NULL,
  Status VARCHAR(10) NOT NULL,
  Gehalt NUMBER,
  CONSTRAINT MaxJunior CHECK (NOT(Status = 'Junior') OR Gehalt <= 2500)
); 
Beispiel-Inserts für das Provozieren von Verstößen gegen die Checks:
insert into Verkaeufer (VNR, VName, Status, Gehalt)  values (666, 'Hans Test', 'Senior', 2000);
insert into Verkaeufer (VNR, VName, Status, Gehalt)  values (1666, 'Hans Junior', 'Junior', 3000);


Oracle/SQLDeveloper

Wenn ihr in der FH z.B. auf einem Windows-Rechner angemeldet seid, findet ihr Installationsdateien für Oracle 11 Express und SQLDeveloper in meinem Profilverzeichnis:
"\\FILESERVER\knauf\Oracle" als URL im Explorer eingeben.
Ich habe folgende Dateien bereitgestellt (von http://www.oracle.com/technetwork/products/express-edition/downloads/index.html):

SQLDeveloper

Die Zip-Datei, die ich bereitgestellt habe, hat bei mir nur eine Serie von Fehlermeldungen "Das Programm kann nicht gestartet werden, da MSVCR71.dll auf dem Computer fehlt", gefolgt von "Unable to launch the Java Virtual Machine. Located at path '..\..\jdk\jre\bin\client\jvm.dll") gemacht:
SQLDeveloper-Startfehler
Die Lösung ist relativ simpel: das Verzeichnis der Java-Runtime dem PATH zufügen und danach das Ding starten:
set PATH=C:\Temp\sqldeveloper\jdk\jre\bin
C:\Temp\sqldeveloper\sqldeveloper.exe
Es könnte auch klappen, wenn man in der PATH-Umgebungsvariable den Pfad zur auf dem Rechner installierten Java-Version einträgt.


Mehr als 50 Ergebnisse im Fenster "Abfrageergebnis" anzeigen
Menü "Extras" => "Voreinstellungen". Dort unter "Datenbank" => "Erweitert" die "SQL-Array-Abrufgröße" auf das Maximum von 500 stellen:
SQL-Array-Abrufgröße


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 3.0 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;
show errors TRIGGER myTrigger;



Zugriff auf FH-Oracle

Linux

Hr. Heimrich sagt:
Zuerst braucht man einen Tunnel von außen zum Server. Mit Ubuntu kann man das z.B. so machen:
ssh heimrich@login2.cs.hs-rm.de -L 1521:oracle2:1521

Dann muss man den SQl-Developer starten und eine neue Verbindung einrichten. Im folgenden Bild sieht man, was eingegeben werden muss. Wichtig ist, dass bei "SID" p001 eingegeben wird. So heißt die Datenbank.

SQLDeveloper mit Tunnel unter Linux


Windows

Basierend auf: http://adamsquicklog-webissues.blogspot.de/2011/02/connecting-sqldeveloper-to-remote-db.html


Normalformen

Zu Blatt 3, Aufgabe 2.2.c:
Es gibt die funktionalen Abhängigkeiten "F->C" und "C->F". Das heißt, dass die Spalten "FG" und "CG" Schlüsselkandidaten sind. Wenn man sich für eines der Spaltenpaare als Primärschlüssel entscheidet, wäre eigentlich die zweite Normalform verletzt, da dann eine Abhängigkeit von einem Teil des Primärschlüssels besteht (partielle Abhängigkeit).


In "Datenbanken - Konzepte und Sprachen" von Saake/Sattler/Heuer (4. Auflage) findet sich auf Seite 178 allerdings folgendes:
Zu beachten ist, dass das partiell abhängige Atribut nur stört, wenn es kein Primattribut ist. Primattribute sind Attribute aus Schlüsseln des Relationenschemas. Attribute, die in Schlüsseln des Relationenschemas vorkommen, werden also nicht auf partielle Abhängigkeiten geprüft.

Das Buch unterscheidet zwischen "Schlüssel" (auch "Schlüsselkandidat" genannt, eine minimale Menge von Attributen, die restlichen Attribute eindeutig identifiziert) und "Primärschlüssel" (falls es mehrere Schlüssel gibt, dann ist dies einer davon, der vom Designer der Datenbank ausgewählt wurde).

Gemäß meiner Musterlösung verstößt die Tabelle allerdings gegen die BNCF.

Stand 10.07.2013
Historie:
17.04.2013: Erstellt
22.04.2013: Bewertung Blatt 1 von 670996
24.04.2013: Bewertung Blatt 2 Gruppe D
26.04.2013: restliche Bewertungen Blatt 2
28.04.2013: Punktzahlen Blatt 2 Aufgabe 2 korrigiert: ich bin fälschlicherweise von einem Maximum von 1 Punkte ausgegeben, es gibt aber 2 Punkte darauf.
08.05.2013: Korrektur Bewertung Blatt 2 Aufgabe 2 271273, Hinweis Endbewertung
17.05.2013: Bewertung Blatt 3
22.05.2013: Anleitung für Tunnel zur FH-Oracle
23.05.2013: Hinweis zur 2NF
25.05.2013: Bewertung Blatt 4, Nachbewertung Blatt 1 von 557117
27.05.2013: Bewertung Blatt 4 von 865278 war in falscher Zeile
29.05.2013: Nachbewertung Blatt 1 von 865278, Hinweise zu Blatt 5
05.06.2013: Bewertung Blatt 5
11.06.2013: Hinweis zu SQLDeveloper-Einstellung "SQL-Array-Abrufgröße"
12.06.2013: Bewertung Blatt 6 + Musterlösung; fehlende Bewertungen Blatt 5 von 673067 und 670996
19.06.2013: Hinweise zu SQLDeveloper und Prozeduren, Aufgabe 6d als Prozedur
26.06.2013: Beispieltrigger
01.07.2013: Punktzahlen Blatt 1 - 6
02.07.2013: Punktzahlen Blatt 1 - 6 von 174473
07.07.2013: Bewertung Projektaufgabe
10.07.2013: Bewertung Projektaufgabe von 573228