Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
modul:m290_guko:learningunits:lu07:theorie:b_sql_dml [2025/09/28 18:13] – gkoch | modul:m290_guko:learningunits:lu07:theorie:b_sql_dml [2025/09/28 20:07] (aktuell) – gkoch | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== LU07b – SQL-DML: Daten einfügen, ändern, löschen | + | ====== LU07b – SQL-DML: |
+ | ===== Einführung ===== | ||
In LU05 haben wir die **DDL** (Data Definition Language) kennengelernt, | In LU05 haben wir die **DDL** (Data Definition Language) kennengelernt, | ||
Zeile 17: | Zeile 17: | ||
> **Wichtig: | > **Wichtig: | ||
- | > **DML** = **Data Manipulation Language**: %%INSERT%%, %%UPDATE%%, %%DELETE%%. (//Read// erfolgt mit %%SELECT%% und gehört streng genommen zur **DQL**, wird im Alltag bei CRUD aber oft mitgemeint.) | + | > **DML** = **Data Manipulation Language**: %%INSERT%%, %%UPDATE%%, %%DELETE%%. (//Read// erfolgt mit %%SELECT%% und gehört streng genommen zur **DQL**, wird im Alltag bei CRUD((Create, Read, Update, Delete Operationen)) |
Bisher haben wir neue Datensätze über die **Webstorm-Oberfläche** eingefügt (//Edit Data > " | Bisher haben wir neue Datensätze über die **Webstorm-Oberfläche** eingefügt (//Edit Data > " | ||
Zeile 23: | Zeile 23: | ||
{{: | {{: | ||
- | Das funktioniert, | + | Das funktioniert, |
Darum machen wir das ab jetzt **programmatisch mit SQL**. | Darum machen wir das ab jetzt **programmatisch mit SQL**. | ||
Zeile 29: | Zeile 29: | ||
%%INSERT%% entspricht **Create**, %%SELECT%% entspricht **Read**, %%UPDATE%% entspricht **Update** und %%DELETE%% entspricht **Delete**. | %%INSERT%% entspricht **Create**, %%SELECT%% entspricht **Read**, %%UPDATE%% entspricht **Update** und %%DELETE%% entspricht **Delete**. | ||
- | Mit DML können wir Daten also gezielt **einfügen**, | ||
- | ===== Lernziele | + | ===== INSERT Statement |
- | * Ich kann Daten **einfügen** (// | + | Der Befehl |
- | | + | |
- | ===== INSERT | + | **Syntax (Einzelzeile)** |
+ | <WRAP center box 80% round>< | ||
+ | INSERT | ||
+ | VALUES (wert1, wert2, wert3); | ||
+ | </ | ||
+ | |||
+ | **Syntax (mehrere Zeilen auf einmal)** | ||
+ | <WRAP center box 80% round>< | ||
+ | INSERT INTO tabellenname (spalte1, spalte2, spalte3) | ||
+ | VALUES (wert1a, wert2a, wert3a), | ||
+ | | ||
+ | </ | ||
+ | |||
+ | **Syntax (INSERT ... SELECT)** | ||
+ | <WRAP center box 80% round>< | ||
+ | INSERT INTO zieltabelle (spalte1, spalte2, spalte3) | ||
+ | SELECT quelle_spalte1, | ||
+ | FROM quelle | ||
+ | WHERE bedingung; | ||
+ | </ | ||
+ | |||
+ | --- | ||
**Variante A: Spalten explizit angeben** | **Variante A: Spalten explizit angeben** | ||
Zeile 42: | Zeile 61: | ||
VALUES ('Lost in Translation', | VALUES ('Lost in Translation', | ||
</ | </ | ||
+ | |||
+ | <WRAP center box 80% round> | ||
+ | ^ film_id ^ title ^ director | ||
+ | | 1 | Lost in Translation | Sofia Coppola | ||
+ | </ | ||
**Variante B: Mehrere Zeilen auf einmal** | **Variante B: Mehrere Zeilen auf einmal** | ||
Zeile 50: | Zeile 74: | ||
(' | (' | ||
</ | </ | ||
+ | |||
+ | <WRAP center box 80% round> | ||
+ | ^ film_id ^ title ^ director | ||
+ | | 1 | Lost in Translation | ||
+ | | 2 | Inception | ||
+ | | 3 | Arrival | ||
+ | </ | ||
**Variante C: INSERT ... SELECT (Daten aus einer anderen Tabelle übernehmen)** | **Variante C: INSERT ... SELECT (Daten aus einer anderen Tabelle übernehmen)** | ||
- | Mit %%INSERT ... SELECT%% können Datensätze direkt | + | Mit %%INSERT ... SELECT%% können Datensätze direkt aus einer anderen |
- | Das ist besonders nützlich, wenn wir Daten aus einer grossen Tabelle (z. B. // | + | Das ist z. B. praktisch, wenn Daten aus // |
<WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
Zeile 62: | Zeile 93: | ||
</ | </ | ||
- | > **Hinweis: | + | > **Hinweis: |
- | + | ||
- | > **Tipps: | + | |
- | > • Zahlen/Jahr ohne Anführungszeichen, | + | |
- | > • Fehlermeldung „duplicate key“? → Wahrscheinlich wird versucht, denselben // | + | |
- | + | ||
- | ===== UPDATE – Daten ändern ===== | + | |
- | Sind bereits Daten in der Tabelle vorhanden, können wir sie mit dem // | + | |
- | + | ||
- | **Wichtig: Immer mit %%WHERE%% einschränken!** Das Statement würde auch ohne %%WHERE%%-Clause funktionieren, | + | |
- | + | ||
- | <WRAP center box 80% round>< | + | |
- | -- Regie-Credit korrigieren (gezielt über Primärschlüssel) | + | |
- | UPDATE favourite_film | + | |
- | SET director = 'C. Nolan' | + | |
- | WHERE film_id = 2; | + | |
- | </ | + | |
- | + | ||
- | **Mehrere Spalten in einem Datensatz auf einmal ändern** | + | |
- | <WRAP center box 80% round>< | + | |
- | UPDATE favourite_film | + | |
- | SET title = ' | + | |
- | WHERE film_id = 3; | + | |
- | </ | + | |
- | + | ||
- | **Semantische Updates (vorsichtig!)** | + | |
- | <WRAP center box 80% round>< | + | |
- | -- Alle Filme mit leerem Hauptdarsteller: | + | |
- | UPDATE favourite_film | + | |
- | SET star1 = ' | + | |
- | WHERE star1 IS NULL; | + | |
- | </ | + | |
- | + | ||
- | > **Warnung: | + | |
- | + | ||
- | ===== DELETE – Daten löschen ===== | + | |
- | Mit dem // | + | |
- | + | ||
- | **Gezielt löschen (über Primärschlüssel)** | + | |
- | <WRAP center box 80% round>< | + | |
- | DELETE FROM favourite_film | + | |
- | WHERE film_id = 1; | + | |
- | </ | + | |
- | + | ||
- | **Mehrere Datensätze in einem Schritt (IN-Liste)** | + | |
- | <WRAP center box 80% round>< | + | |
- | DELETE FROM favourite_film | + | |
- | WHERE film_id IN (2, 3); | + | |
- | </ | + | |
- | + | ||
- | **Aufräumen nach Import (z. B. fehlerhafte Jahrgänge)** | + | |
- | <WRAP center box 80% round>< | + | |
- | DELETE FROM favourite_film | + | |
- | WHERE released_year < 1900 OR released_year IS NULL; | + | |
- | </ | + | |
- | + | ||
- | > **Warnung: | + | |
- | + | ||
- | ===== TRUNCATE – Tabelle schnell leeren (ohne WHERE) ===== | + | |
- | %%TRUNCATE%% entfernt **alle** Zeilen einer Tabelle **sehr schnell**. Im Unterschied zu // | + | |
- | * Keine %%WHERE%%-Bedingung möglich (immer die **ganze** Tabelle). | + | |
- | * Setzt den AUTO_INCREMENT-Zähler zurück. | + | |
- | * Kann durch Fremdschlüssel-Constraints blockiert sein. | + | |
- | * Gilt in vielen Systemen als DDL-Operation (ähnlich wie Tabellendefinitionen). | + | |
- | + | ||
- | <WRAP center box 80% round>< | + | |
- | TRUNCATE TABLE favourite_film; | + | |
- | </ | + | |
- | + | ||
- | > **Merke:** Nutzen Sie %%TRUNCATE%% nur, wenn Sie die Tabelle **vollständig leeren** wollen. Für selektives Löschen bleibt //DELETE// die richtige Wahl. | + | |
- | + | ||
- | ===== NULL richtig verstehen ===== | + | |
- | **NULL** bedeutet: //kein Wert vorhanden// (weder 0 noch leerer String). | + | |
- | Abfragen mit %%IS NULL%% bzw. %%IS NOT NULL%%: | + | |
- | + | ||
- | <WRAP center box 80% round>< | + | |
- | -- Filme ohne eingetragenen Star | + | |
- | SELECT film_id, title FROM favourite_film | + | |
- | WHERE star1 IS NULL; | + | |
- | + | ||
- | -- Filme mit eingetragenem Star | + | |
- | SELECT film_id, title, star1 FROM favourite_film | + | |
- | WHERE star1 IS NOT NULL; | + | |
- | </ | + | |
- | + | ||
- | > **Merke:** Vergleiche mit //=// oder //<>// | + | |
- | + | ||
- | ===== Praxis: Sicher arbeiten (SELECT-Variante & Dry-Run) ===== | + | |
- | Vor jedem //UPDATE// bzw. //DELETE// zuerst mit **SELECT testen**, ob die **gleiche WHERE-Bedingung** die gewünschten Zeilen trifft: | + | |
- | + | ||
- | <WRAP center box 80% round>< | + | |
- | -- Dry-Run: Welche Zeilen wären betroffen? | + | |
- | SELECT film_id, title FROM favourite_film | + | |
- | WHERE released_year >= 2020; | + | |
- | </ | + | |
- | + | ||
- | Wenn korrekt: erst dann %%UPDATE%%/ | + | |