# Aufgabe 1
> Dauer: 2 h
## 1)

## 2) Datenbankentwurf in Relationenschreibweise
```sql
use emensawerbeseite;
-- Tabelle 'Ersteller' erstellen
CREATE TABLE IF NOT EXISTS Ersteller (
EMail VARCHAR(255) PRIMARY KEY,
Name VARCHAR(255) DEFAULT 'anonym'
);
-- Tabelle 'Wunschgericht' erstellen
CREATE TABLE IF NOT EXISTS Wunschgericht (
ID INT AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
Beschreibung TEXT,
Erstellungsdatum DATE NOT NULL,
Ersteller_EMail VARCHAR(255) NOT NULL,
FOREIGN KEY (Ersteller_EMail) REFERENCES Ersteller(EMail)
);
```
## 6)
### a)
````sql
select * from wunschgericht order by Erstellungsdatum desc limit 5;
````
### b)
````sql
-- basierend auf M3 6) 4)
select ersteller.Name,
count(Ersteller_EMail) as anzahl from wunschgericht, ersteller where ersteller.EMail = wunschgericht.Ersteller_EMail
group by Ersteller_EMail
order by anzahl desc ;
````
---
# Aufgabe 2
> Dauer: 2h
Bei der Übergabe von Daten in die DB müssen diese geprüft werden.
Bei der Ausgabe von Daten aus der DB im HTML Code müssen diese Maskiert werden.
````php
// wunschgericht.php
// Zeile 33
$sql_ersteller_exists = "SELECT * FROM ersteller WHERE EMail = '" . $ersteller_email . "'";
$sql_ersteller_exists = "SELECT * FROM ersteller WHERE EMail = '" . mysqli_real_escape_string($link, $ersteller_email) . "'";
// Zeile 36
$sql_ersteller = "INSERT INTO ersteller(EMail, Name) VALUES ('" . $ersteller_email . "','" . $ersteller_name . "')";
$sql_ersteller = "INSERT INTO ersteller(EMail, Name) VALUES ('" . mysqli_real_escape_string($link, $ersteller_email) . "','" . mysqli_real_escape_string($link, $ersteller_name) . "')";
// Zeile 42
$sql = "INSERT INTO wunschgericht(Name, Beschreibung, Erstellungsdatum, Ersteller_EMail) VALUES ('" . $gericht_name . "','" . $gericht_beschreibung . "','". $date ."','" . $ersteller_email . "')";
$sql = "INSERT INTO wunschgericht(Name, Beschreibung, Erstellungsdatum, Ersteller_EMail) VALUES ('" . mysqli_real_escape_string($link, $gericht_name) . "','" . mysqli_real_escape_string($link, $gericht_beschreibung) . "','".$date."','" . mysqli_real_escape_string($link, $ersteller_email) . "')";
?>
````
````php
// index.php
// Zeile 43
$sql_besucher = "UPDATE besucher_counter SET besucher =".$besucherCount;
$sql_besucher = "UPDATE besucher_counter SET besucher =". mysqli_real_escape_string($link, $besucherCount);
// Zeile 190
$tabelle .= "
| " . $row_gerichte['name'] . " " . $allergene . " | " . $preisintern . "€ | " . $preisextern . "€ | Kein Bild in der Datenbank |
";
$tabelle .= "| " . htmlspecialchars($row_gerichte['name']) . " " . htmlspecialchars($allergene) . " | " . htmlspecialchars($preisintern) . "€ | " . htmlspecialchars($preisextern) . "€ | Kein Bild in der Datenbank |
";
// Zeile 202
$verwendete_allergene_string .= "".$row_allergen['code']." ". $row_allergen['name']. ", ";
$verwendete_allergene_string .= "". htmlspecialchars($row_allergen['code']) ." ". htmlspecialchars($row_allergen['name']) . ", ";
// Zeile 214f
echo $besucherCount;
echo $newletterCount;
echo htmlspecialchars($besucherCount);
echo htmlspecialchars($newletterCount);
// Zeile 220
echo $ausgabe["COUNT(id)"];
echo htmlspecialchars($ausgabe["COUNT(id)"]);
````
Bei der Newsletteranmeldung sollte man sich auch ggf. überlegen, wie man die Eingaben prüft un zu vermeiden, das schadhafter Code gespeichert und später abgerufen wird.
# Aufgabe 4
1. Eindeutigkeit für die Kombination aus Gericht und Kategorie sicherstellen
````sql
ALTER TABLE gericht_hat_kategorie
ADD CONSTRAINT gericht_kategorie_unique UNIQUE (gericht_id, kategorie_id);
````
2. In der Tabelle gericht soll eine Abfrage nach Name beschleunigt werden.
````sql
ALTER TABLE gericht
ADD INDEX idx_name (name);
````
3. Bei Löschung eines Gerichts sollen
1) die zugehörigen Zuordnungen zu einer Kategorie sowie
````sql
ALTER TABLE gericht_hat_kategorie
DROP FOREIGN KEY gericht_hat_kategorie_ibfk_1, -- (gericht_id) -> gericht(id)
ADD CONSTRAINT gericht_hat_kategorie_ibfk_1_new
FOREIGN KEY (gericht_id) REFERENCES gericht(id)
ON DELETE CASCADE;
````
2) die zugehörigen Zuordnungen zu Allergenen automatisch mit gelöscht werden.
````sql
ALTER TABLE gericht_hat_allergen
DROP FOREIGN KEY gericht_hat_allergen_ibfk_2, -- (gericht_id) -> gericht(id)
ADD CONSTRAINT gericht_hat_allergen_ibfk_2_new
FOREIGN KEY (gericht_id) REFERENCES gericht(id)
ON DELETE CASCADE;
````
4. Eine Kategorie kann nur dann gelöscht werden, wenn
1) dieser keine Gerichte zugeordnet sind und
````sql
ALTER TABLE gericht_hat_kategorie
ADD CONSTRAINT fk_gericht_hat_kategorie_kategorie_id
FOREIGN KEY (kategorie_id) REFERENCES kategorie(id)
ON DELETE RESTRICT;
````
2) diese keine Kindkategorien besitzt.
````sql
ALTER TABLE kategorie
ADD CONSTRAINT fk_kategorie_eltern_id
FOREIGN KEY (eltern_id) REFERENCES kategorie(id)
ON DELETE RESTRICT;
````
5. Wird der Code eines Allergens verändert, so ändert sich dieser Code automatisch in den referenzierenden Datensätzen.
````sql
ALTER TABLE gericht_hat_allergen
DROP FOREIGN KEY gericht_hat_allergen_ibfk_1, -- (code) -> allergen(code)
ADD CONSTRAINT gericht_hat_allergen_ibfk_1_new
FOREIGN KEY (code) REFERENCES allergen(code)
ON UPDATE CASCADE;
````
6. Eine Kombination aus ``gericht_id`` und ``kategorie_id`` in ``gericht_hat_kategorie`` soll als Primärschlüssel dienen.
````sql
ALTER TABLE gericht_hat_kategorie
ADD PRIMARY KEY (gericht_id, kategorie_id);
````