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 16:27] – 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, | ||
| - | + | Folgender SQL-Code erzeugt eine **leere** Tabelle // | |
| - | Folgender SQL-Code erzeugt eine **leere** Tabelle // | + | |
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| CREATE TABLE favourite_film | CREATE TABLE favourite_film | ||
| ( | ( | ||
| - | | + | |
| title VARCHAR(100), | title VARCHAR(100), | ||
| director VARCHAR(50), | director VARCHAR(50), | ||
| Zeile 17: | Zeile 16: | ||
| </ | </ | ||
| - | > **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((Create, Read, Update, Delete Operationen)) aber mitgemeint.) | ||
| 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 > " | ||
| - | {{: | ||
| - | 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**, | ||
| + | ===== INSERT Statement ===== | ||
| + | Der Befehl %%INSERT%% fügt neue Datensätze in eine Tabelle ein. Dabei muss angegeben werden, **in welche Spalten** die Werte eingefügt werden. | ||
| - | + | **Syntax | |
| - | ===== Lernziele ===== | + | |
| - | * Ich kann Daten **einfügen** (//INSERT//), **ändern** (// | + | |
| - | * Ich erkenne typische **Fehlerquellen** (fehlendes %%WHERE%%, falsche Datentypen, Schlüsselverletzungen). | + | |
| - | + | ||
| - | ===== INSERT – Daten einfügen ===== | + | |
| - | + | ||
| - | **Variante A: Spalten explizit angeben** | + | |
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| - | INSERT INTO favourite_film | + | INSERT INTO tabellenname |
| - | VALUES (' | + | VALUES (wert1, wert2, wert3); |
| </ | </ | ||
| - | **Variante B: Mehrere | + | **Syntax (mehrere |
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| - | INSERT INTO favourite_film | + | INSERT INTO tabellenname |
| - | VALUES | + | VALUES (wert1a, wert2a, wert3a), |
| - | | + | |
| - | (' | + | |
| </ | </ | ||
| - | **Variante C: INSERT ... SELECT | + | **Syntax (INSERT ... SELECT)** |
| - | Mit %%INSERT ... SELECT%% können Datensätze direkt **aus einer bestehenden Tabelle** in eine andere kopiert werden. | + | |
| - | Das ist besonders nützlich, wenn wir Daten aus einer grossen Tabelle (z. B. // | + | |
| - | + | ||
| - | Voraussetzung: | + | |
| - | Wir müssen also beim Einfügen einen künstlichen Wert erzeugen, z. B. mit der SQL-Funktion %%UUID()%%. | + | |
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| - | INSERT INTO favourite_film | + | INSERT INTO zieltabelle |
| - | SELECT | + | SELECT |
| - | FROM imdb_top_1000 | + | FROM quelle |
| - | WHERE Released_Year >= 2000; | + | WHERE bedingung; |
| </ | </ | ||
| - | > **Hinweis: | + | --- |
| - | > **UUID()** erzeugt eine eindeutige ID als Ersatz für das fehlende ISAN. | + | |
| - | + | ||
| - | + | ||
| - | > **Tipps: | + | |
| - | > Zahlen/Jahr ohne Anführungszeichen, | + | |
| - | > Fehlermeldung „duplicate key“? → Der //ISAN// existiert bereits (Primärschlüssel). | + | |
| - | + | ||
| - | ===== UPDATE – Daten ändern ===== | + | |
| - | Sind bereits Daten in der Tabelle vorhanden, können wir sie mit dem //UPDATE//-Befehl aktualisieren. | + | |
| - | + | ||
| - | **Wichtig: Immer mit %%WHERE%% einschränken!** Das Statement würde auch ohne %%WHERE%%-Clause funktionieren, | + | |
| + | **Variante A: Spalten explizit angeben** | ||
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| - | -- Regie-Credit korrigieren | + | INSERT INTO favourite_film |
| - | UPDATE favourite_film | + | VALUES ('Lost in Translation', 'Sofia Coppola', 2003, ' |
| - | SET director = 'C. Nolan' | + | |
| - | WHERE ISAN = '0000-0000-3C2D-0000-0-0000-0000-X'; | + | |
| </ | </ | ||
| - | **Mehrere Spalten in einem Datensatz auf einmal ändern** | + | <WRAP center box 80% round> |
| - | <WRAP center box 80% round>< | + | ^ film_id ^ title ^ director |
| - | UPDATE favourite_film | + | | 1 | Lost in Translation | Sofia Coppola |
| - | SET title = ' | + | </ |
| - | WHERE ISAN = ' | + | |
| - | </ | + | |
| - | **Semantische Updates (vorsichtig!)** | + | **Variante B: Mehrere Zeilen auf einmal** |
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| - | -- Alle Filme mit leerem Hauptdarsteller: | + | INSERT INTO favourite_film |
| - | UPDATE favourite_film | + | VALUES |
| - | SET star1 = 'TBD' | + | ('Inception', ' |
| - | WHERE star1 IS NULL; | + | |
| </ | </ | ||
| - | > **Warnung: | + | <WRAP center box 80% round> |
| + | ^ film_id ^ title ^ director | ||
| + | | 1 | Lost in Translation | ||
| + | | 2 | Inception | ||
| + | | 3 | Arrival | ||
| + | </WRAP> | ||
| - | ===== DELETE – Daten löschen ===== | + | **Variante C: INSERT ... SELECT (Daten aus einer anderen Tabelle übernehmen)** |
| - | Mit dem // | + | Mit %%INSERT ... SELECT%% |
| + | Das ist z. B. praktisch, wenn Daten aus // | ||
| - | **Gezielt löschen (über Primärschlüssel)** | ||
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| - | DELETE FROM favourite_film | + | INSERT INTO favourite_film (title, director, released_year, |
| - | WHERE ISAN = ' | + | SELECT |
| - | </ | + | FROM imdb_top_1000 |
| - | + | WHERE Released_Year | |
| - | **Mehrere Datensätze in einem Schritt | + | |
| - | <WRAP center box 80% round>< | + | |
| - | DELETE FROM favourite_film | + | |
| - | WHERE ISAN IN ( | + | |
| - | ' | + | |
| - | ' | + | |
| - | ); | + | |
| - | </ | + | |
| - | + | ||
| - | **Aufräumen nach Import (z. B. fehlerhafte Jahrgänge)** | + | |
| - | <WRAP center box 80% round>< | + | |
| - | DELETE FROM favourite_film | + | |
| - | WHERE released_year | + | |
| - | </ | + | |
| - | + | ||
| - | > **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 häufig Zähler (z. B. AUTO_INCREMENT) 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 | + | |
| - | WHERE star1 IS NULL; | + | |
| - | + | ||
| - | -- Filme mit eingetragenem Star | + | |
| - | SELECT ISAN, 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 ISAN, title FROM favourite_film | + | |
| - | WHERE released_year | + | |
| </ | </ | ||
| - | Wenn korrekt: erst dann %%UPDATE%%/ | + | > **Hinweis:** Mit %%WHERE%% |