SQL Data Definition Language

Wang

Bekanntes Mitglied
Hallo,

es wäre sehr nett, wenn sich jemand meine Lösung zu dieser Aufgabe ansehen könnte, da ich in SQL leider noch ein Newbie bin (Vorlesung: Datenbanken):

sqlt.png


(a)

SQL:
CREATE TABLE L
(
	lnr VARCHAR (10) ,
	lname VARCHAR (40) NOT NULL,
	sitz VARCHAR (40),
	PRIMARY KEY(lnr)
);

CREATE TABLE T
(
	tnr VARCHAR (10),
	tname VARCHAR (40) NOT NULL,
	farbe VARCHAR (40),
	gewicht INT,
	preis VARCHAR (40),
	PRIMARY KEY(tnr)
);

CREATE TABLE P
(
	pnr VARCHAR (10),
	pname VARCHAR (40) NOT NULL,
	ort VARCHAR (40),
	PRIMARY KEY(pnr)
);

CREATE TABLE LTP
(
	lnr VARCHAR (10),
	tnr VARCHAR (10),
	pnr VARCHAR (10),
	menge INT,
	PRIMARY KEY(lnr, tnr, pnr),
	FOREIGN KEY(lnr, tnr, pnr) references L(lnr), T(tnr), P(pnr) ON DELETE CASCADE ON UPDATE CASCADE
);

(b)

SQL:
ALTER TABLE L ADD status INT;

(c)

SQL:
ALTER TABLE T MODIFY preis FLOAT (2);

(d)

SQL:
ALTER TABLE T DROP preis;

(e)

SQL:
DROP TABLE L, T, P, LTP;


Ich danke Euch vielmals für Eure Hilfe und Mühe!

Gruß
Wang
 

faetzminator

Gesperrter Benutzer
Ich würde das einfach schnell in einer DB testen... Und da ich gerade keine zur Hand hab, hier eine Gegenfrage: Warum testest du das nicht mit einer laufenden DB :) ?
Aber grundsätzlich kann ich keinen schwerwiegenden Fehler erkennen.
 

Wang

Bekanntes Mitglied
Ich würde das einfach schnell in einer DB testen... Und da ich gerade keine zur Hand hab, hier eine Gegenfrage: Warum testest du das nicht mit einer laufenden DB :) ?

Was bietet sich da am besten an; "Oracle Database 11g"?
Ich bin bzgl. SQL und Datenbanken leider der totale Newbie...

Aber grundsätzlich kann ich keinen schwerwiegenden Fehler erkennen.

Die Aufgabenstellung gibt einem ja einigen Spielraum... würdest Du am Ende der (a) sagen, dass das mit dem FOREIGN KEY so in Ordnung ist?

SQL:
CREATE TABLE LTP
(
    lnr VARCHAR (10),
    tnr VARCHAR (10),
    pnr VARCHAR (10),
    menge INT,
    PRIMARY KEY(lnr, tnr, pnr),
    FOREIGN KEY(lnr, tnr, pnr) REFERENCES L(lnr), T(tnr), P(pnr) ON DELETE CASCADE ON UPDATE CASCADE
);
 

Evil-Devil

Top Contributor
Eine Spalte fügt man mit "alter table <tabellenname> add column <spaltenname> <typ> <zusätzliche optionen>" an.

Das sollte in nahezu allen aktuellen SQL DBMS identisch sein. Bei den Constraints weiß ich leider selbst nicht wie das abläuft. Ich kümmere mich um die Referenzielle Intigrität immer selbst.
 

Wang

Bekanntes Mitglied
Die Aufgabe wurde leider erweitert... Ich habe zwar die Lösung, kann sie aber nicht nachvollziehen - da hilft auch keine DB. Hier die Aufgabenstellung und Beispielrelationen, die die Bearbeitung erleichtern sollen:

difficult.png


Lösung:

SQL:
SELECT DISTINCT tname,gewicht
FROM T,LTP LTP1,LTP LTP2
WHERE LTP1.pnr = ‘P1’
AND LTP2.pnr = ‘P2’
AND LTP1.tnr = T.tnr
AND LTP1.tnr = LTP2.tnr;


Fragen:
- Mir bereitet die Formulierung in Zeile 2 etwas Schwierigkeiten... Sind LTP1 und LTP2 einfach nur eine Art Zugriffsvariablen?
- Wozu dient die Zeile 5; damit werden doch alle Teilenummer aus LTP ausgegeben, die in der Relation T vorhanden sind, was doch total überflüssig ist?

Nochmals vielen Dank!
 

Evil-Devil

Top Contributor
Das AS kann man in den meisten DMBS weglassen. Es erhöht lediglich die Lesbarkeit.

In dem Zusammenhang hatte ich zumindest unter SQL mal einen nervigen Bug. Sobald man dort für eine Tabelle einen Alias anlegt ist sie innerhalb des Queries ausschließlich über den Alias ansprechbar.

@Fragen: Na über Zeile 5 erhältst die den Zugriff auf den Namen deiner Teile. Ohne die Verbindung wäre die Verbindung nicht gegeben.
 

Evil-Devil

Top Contributor
Aber bei einer Abfrage wie [c]FROM T, LTP AS LTP1, LTP AS LTP2[/c], was soll denn da passieren, wenn ich auf [c]LTP[/c] zugreifen will ;) ?

Im besagten Beispiel schmeißt MySQL einen Fehler, dass es die Tabelle LTP nicht kennt. Kann sein das es in einer der Unterversionen von 5.x.x inzwischen geändert wurde, aber auf unserem 5.x.x System hat man mit diesen Umstand zu leben. Wobei es an sich sogar einleuchtet, denn der Tabellenbezeichner wird für den Lebenszeitraum der Abfrage geändert.

War halt eine nervige Angelegenheit als man auf das Problem gestoßen ist und nicht wusste das es daran lag, dass MySQL eine Fehlermeldung schmeißt jene Tabelle würde nicht existieren.
 

Wang

Bekanntes Mitglied
@Fragen: Na über Zeile 5 erhältst die den Zugriff auf den Namen deiner Teile. Ohne die Verbindung wäre die Verbindung nicht gegeben.

Leider leuchtet mir das noch nicht ein, obwohl ich schon eine gefühlte Ewigkeit vor diesem Code sitze... Ich gehe mal die Bedeutung der einzelnen Zeilen ab Zeile 3 durch:

Zeile 3: Selektion aller Zeilen aus LTP1, wo die Projektnummer P1 auftaucht
Zeile 4: Selekton aller Zeilen aus LTP2, wo die Projektnummer P2 auftaucht
Zeile 5: Selektion aller Zeilen aus LTP1, deren Teilenummern in der Relation T auftreten [nachdem die Relation T aber alle existierenden Teilenummern enthält, sind das doch gerade die Einträge, die man nach Zeile 3 erhält, sprich es werden hiermit keine Einträge aussortiert ???:L ]
Zeile 6: Selektion aller Zeilen, deren Teilenummern sowohl in LTP1 auftreten als auch in LTP2

Natürlich müssen diese Bedingungen alle gleichzeitig erfüllt sein, ich kann aber nicht verstehen, wozu die Zeile 5 gebraucht wird... Dann hätte man doch zusätzlich auch
Code:
AND LTP2.tnr = T.tnr
schreiben müssen ???:L
 

Evil-Devil

Top Contributor
Zeile 5: Selektion aller Zeilen aus LTP1, deren Teilenummern in der Relation T auftreten [nachdem die Relation T aber alle existierenden Teilenummern enthält, sind das doch gerade die Einträge, die man nach Zeile 3 erhält, sprich es werden hiermit keine Einträge aussortiert ???:L ]
Schau mal in deiner Select Zeile. Dort wird auf TName zugegriffen und die Spalte stammt aus T. Solange du keine passende Zuweisung zu T hast kann TName nicht ausgegeben werden. DEnn TName existiert nur in T und nirgendwo sonst ;)
 

Wang

Bekanntes Mitglied
Schau mal in deiner Select Zeile. Dort wird auf TName zugegriffen und die Spalte stammt aus T. Solange du keine passende Zuweisung zu T hast kann TName nicht ausgegeben werden. DEnn TName existiert nur in T und nirgendwo sonst ;)

Macht man das der DB aber nicht bereits mit dem
Code:
FROM T
aus
Code:
FROM T,LTP LTP1,LTP LTP2
klar?
 

Evil-Devil

Top Contributor
Nein.
Das FROM legt lediglich fest welche Tabellen abgefragt werden sollen. Wie die zusammenhängen musst du SQL mit auf den Weg geben.

Wenn du die Zeile 5 weglassen würdest, dann würdest du für jeden Eintrag in T einen Eintrag zu deinen Einträgen in LTP1 und LTP2 bekommen. Das willst du doch gar nicht ;)
Dich interessieren doch nur Teile die zu den Projekten gehören.

Denn woher soll SQL wissen das zb. T1 aus LTP1 zu T1 aus T gehört? Über die Referenzielle Intigrität könnte SQL das vermutlich annehmen, aber afaik greift die nur bei Insert/Update/Delete. Wie gesagt, hab die außer bei MS Access nie genutzt.

Ansonsten erstelle dir die Tabellen mit den entsprechenden Daten und probiere die Abfrage einmal mit und ohne Zeile 5 aus ;)
 

Wang

Bekanntes Mitglied
Ich habe alle Tabellen in MySQL 5.5 eingegeben und mit sämtlichen Befehlen "gespielt" um mich mit der Materie besser vertraut zu machen. Allerdings erhalte ich nach Eingabe von

SQL:
SELECT DISTINCT tname,gewicht
FROM T,LTP LTP1,LTP LTP2
WHERE LTP1.pnr = ‘P1’
AND LTP2.pnr = ‘P2’
AND LTP1.tnr = T.tnr
AND LTP1.tnr = LTP2.tnr;

den folgenden Fehler:

ERROR 1054 (42S22): Unknown column 'LTP.tnr' in 'where clause'

Weiß jemand woran das liegt?

EDIT:
Hat sich erledigt, nachdem ich den Command Line Client geschlossen und erneut gestartet habe... Ist nicht meine Woche...
 
Zuletzt bearbeitet:

Neue Themen


Oben