Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
modul:m290_guko:learningunits:lu08:theorie:e_fk-abfragen [2025/10/11 08:52] – angelegt gkoch | modul:m290_guko:learningunits:lu08:theorie:e_fk-abfragen [2025/10/11 09:32] (aktuell) – gkoch | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== LU08e – Referenzaktionen testen | + | ====== LU08e – Referenzaktionen testen ====== |
- | ===== 4.1) Testdaten anlegen ===== | + | Im Fachmodell sind beide FKs **RESTRICT**. Für die Didaktik zeigen wir zusätzlich *Demo-Varianten*, um |
- | <code sql> | + | **CASCADE** und **SET NULL** sichtbar zu machen |
- | -- Personen | + | |
- | INSERT INTO person(name) | + | |
- | VALUES (' | + | |
- | -- Film | + | ===== 1) RESTRICT beobachten ===== |
- | INSERT INTO film(title, released_year, director_id) | + | Versuche, ein Land zu löschen, zu dem es Trips gibt (z. B. Italien): |
- | VALUES ('Lost in Translation', | + | <WRAP center box 80% round>< |
- | | + | DELETE |
+ | </ | ||
- | -- Besetzung | + | Versuche, den Kontinent „Europa“ zu löschen: |
- | INSERT INTO film_cast(film_id, person_id, role) | + | <WRAP center box 80% round>< |
- | SELECT f.film_id, p.person_id, | + | DELETE |
- | FROM film f JOIN person p ON p.name IN (' | + | </code></ |
- | WHERE f.title='Lost in Translation'; | + | |
- | </ | + | |
- | ===== 4.2) RESTRICT beobachten | + | ===== 2) Demo: CASCADE (nur zum Beobachten) |
- | Person in Cast kann nicht gelöscht werden: | + | **Hinweis:** Nicht dauerhaft im Produktivschema verwenden — hier nur zum Verstehen der Wirkung. |
- | <code sql> | + | |
- | DELETE FROM person WHERE name=' | + | |
- | </ | + | |
- | ===== 4.3) SET NULL beobachten ===== | + | 1) FK von Trip→Country temporär auf **CASCADE** ändern: |
- | Regie löschen | + | <WRAP center box 80% round><code sql> |
- | <code sql> | + | ALTER TABLE Trip DROP FOREIGN KEY fk_trip_country; |
- | DELETE FROM person WHERE name=' | + | |
- | SELECT film_id, title, director_id FROM film; | + | |
- | </ | + | |
- | ===== 4.4) CASCADE beobachten ===== | + | ALTER TABLE Trip |
- | Film löschen → zugehörige Cast-Zeilen verschwinden: | + | ADD CONSTRAINT fk_trip_country |
- | <code sql> | + | |
- | DELETE | + | |
- | SELECT * FROM film_cast; | + | ON DELETE |
- | </ | + | |
+ | </code></ | ||
- | ===== 4.5) Typische Fehlerbilder | + | 2) Lösche nun das Land „Deutschland“: |
- | * FK-Spalte | + | <WRAP center box 80% round>< |
- | * FK/PK-Datentypen passen nicht (z. B. SIGNED vs. UNSIGNED) ⇒ **Fehler**. | + | DELETE FROM Country WHERE CountryName=' |
- | | + | SELECT * FROM Trip; -- zu DE gehörende Trips sind automatisch gelöscht |
+ | </ | ||
+ | |||
+ | 3) **Zurück** auf RESTRICT stellen (empfohlen): | ||
+ | <WRAP center box 80% round>< | ||
+ | ALTER TABLE Trip DROP FOREIGN KEY fk_trip_country; | ||
+ | |||
+ | ALTER TABLE Trip | ||
+ | ADD CONSTRAINT fk_trip_country | ||
+ | FOREIGN KEY (CountryID) | ||
+ | REFERENCES Country(CountryID) | ||
+ | ON DELETE RESTRICT | ||
+ | ON UPDATE RESTRICT; | ||
+ | </ | ||
+ | |||
+ | ===== 3) Demo: SET NULL (nur zum Beobachten) ===== | ||
+ | **Hinweis:** Fachlich widerspricht SET NULL hier der Regel „Trip gehört zu genau einem Land“. | ||
+ | Wir zeigen es rein technisch. Dafür muss `Trip.CountryID` NULL erlauben: | ||
+ | |||
+ | <WRAP center box 80% round>< | ||
+ | -- 1) Spalte | ||
+ | ALTER TABLE Trip MODIFY CountryID INT NULL; | ||
+ | |||
+ | -- 2) FK auf SET NULL | ||
+ | ALTER TABLE Trip DROP FOREIGN KEY fk_trip_country; | ||
+ | |||
+ | ALTER TABLE Trip | ||
+ | ADD CONSTRAINT fk_trip_country | ||
+ | FOREIGN KEY (CountryID) | ||
+ | REFERENCES Country(CountryID) | ||
+ | ON DELETE SET NULL | ||
+ | ON UPDATE RESTRICT; | ||
+ | |||
+ | -- 3) Land ' | ||
+ | DELETE FROM Country WHERE CountryName=' | ||
+ | SELECT TripID, CountryID, StartDate, EndDate, Price FROM Trip; | ||
+ | </ | ||
+ | |||
+ | **Merke:** **SET NULL** | ||
+ | |||
+ | ===== 4) Aufräumen | ||
+ | <WRAP center box 80% round>< | ||
+ | -- CountryID wieder NOT NULL + FK zurück auf RESTRICT | ||
+ | UPDATE Trip SET CountryID = (SELECT CountryID FROM Country WHERE CountryName=' | ||
+ | WHERE CountryID IS NULL; | ||
+ | |||
+ | ALTER TABLE Trip MODIFY CountryID INT NOT NULL; | ||
+ | |||
+ | ALTER TABLE Trip DROP FOREIGN KEY fk_trip_country; | ||
+ | |||
+ | ALTER TABLE Trip | ||
+ | ADD CONSTRAINT fk_trip_country | ||
+ | FOREIGN KEY (CountryID) | ||
+ | REFERENCES Country(CountryID) | ||
+ | ON DELETE RESTRICT | ||
+ | ON UPDATE RESTRICT; | ||
+ | </code></ | ||