Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

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:34] gkochmodul: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 & Daten einfügen ====== 
 +===== Einführung =====
 In LU05 haben wir die **DDL** (Data Definition Language) kennengelernt, mit der Tabellen angelegt werden. In LU05 haben wir die **DDL** (Data Definition Language) kennengelernt, mit der Tabellen angelegt werden.
  
- +Folgender SQL-Code erzeugt eine **leere** Tabelle //favourite_film// mit den Spalten //film_id//((Automatisch hochzählende ID, eindeutiger Primärschlüssel)), //title//((Filmtitel)), //director//((Regisseur:in)), //released_year//((Veröffentlichungsjahr, vierstellig)), //star1//((Hauptdarsteller:in)):
-Folgender SQL-Code erzeugt eine **leere** Tabelle //favourite_film// mit den Spalten //ISAN//((ISAN steht für „International Standard Audiovisual Number“. Eindeutige Kennung für audiovisuelle Werke – vergleichbar mit ISBN bei Büchern.)), //title//((Filmtitel)), //director//((Regisseur:in)), //released_year//((Veröffentlichungsjahr, vierstellig)), //star1//((Hauptdarsteller:in)):+
  
 <WRAP center box 80% round><code sql> <WRAP center box 80% round><code sql>
 CREATE TABLE favourite_film CREATE TABLE favourite_film
 ( (
-  ISAN CHAR(33) PRIMARY KEY,+  film_id INT AUTO_INCREMENT PRIMARY KEY,
   title VARCHAR(100),   title VARCHAR(100),
   director VARCHAR(50),   director VARCHAR(50),
Zeile 17: Zeile 16:
 </code></WRAP> </code></WRAP>
  
-> **Wichtig:** //ISAN// ist der **Primärschlüssel** → jeder Datensatz darf nur **einmal** vorkommen. //released_year// ist ein Jahresfeld (vierstellig). +> **Wichtig:** //film_id// ist der **Primärschlüssel** → jeder Datensatz erhält automatisch eine eindeutige ID.   
 +**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 > "+"//):  
Zeile 24: Zeile 23:
 {{:modul:m290_guko:learningunits:lu07:theorie:insert_edit_data_coppola.png?nolink&500}}  {{:modul:m290_guko:learningunits:lu07:theorie:insert_edit_data_coppola.png?nolink&500}} 
  
-Das funktioniert, ist aber mühsam und fehleranfällig, wenn viele Daten eingetragen werden müssen.  +Das funktioniert, ist aber mühsam und fehleranfällig, wenn viele Daten eingetragen oder geändert werden müssen.  
 Darum machen wir das ab jetzt **programmatisch mit SQL**.   Darum machen wir das ab jetzt **programmatisch mit SQL**.  
  
Zeile 30: 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**, **ändern** oder **löschen** – schnell, präzise und reproduzierbar. 
  
 +===== 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 (Einzelzeile)**
-===== Lernziele ===== +
-  * Ich kann Daten **einfügen** (//INSERT//), **ändern** (//UPDATE//) und **löschen** (//DELETE//) – und mit %%WHERE%% korrekt einschränken. +
-  * Ich erkenne typische **Fehlerquellen** (fehlendes %%WHERE%%, falsche Datentypen, Schlüsselverletzungen). +
- +
-===== INSERT – Daten einfügen ===== +
- +
-**Variante A: Spalten explizit angeben**+
 <WRAP center box 80% round><code sql> <WRAP center box 80% round><code sql>
-INSERT INTO favourite_film (ISANtitledirector, released_year, star1+INSERT INTO tabellenname (spalte1spalte2spalte3
-VALUES ('0000-0000-2A1B-0000-0-0000-0000-X', 'Lost in Translation', 'Sofia Coppola'2003'Scarlett Johansson');+VALUES (wert1wert2wert3);
 </code></WRAP> </code></WRAP>
  
-**Variante B: Mehrere Zeilen auf einmal**+**Syntax (mehrere Zeilen auf einmal)**
 <WRAP center box 80% round><code sql> <WRAP center box 80% round><code sql>
-INSERT INTO favourite_film (ISANtitledirector, released_year, star1+INSERT INTO tabellenname (spalte1spalte2spalte3
-VALUES +VALUES (wert1awert2awert3a), 
-  ('0000-0000-3C2D-0000-0-0000-0000-X''Inception''Christopher Nolan', 2010, 'Leonardo DiCaprio'), +       (wert1bwert2bwert3b);
-  ('0000-0000-4E3F-0000-0-0000-0000-X', 'Arrival', 'Denis Villeneuve'2016'Amy Adams');+
 </code></WRAP> </code></WRAP>
  
-**Variante C: INSERT ... SELECT (Daten aus einer anderen Tabelle übernehmen)**   +**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. //imdb_top_1000//) in unsere eigene Tabelle übernehmen möchten.   +
- +
-Voraussetzung: Die Spalten passen zueinander. In unserem Fall fehlt in //imdb_top_1000// die Spalte //ISAN//  +
-Wir müssen also beim Einfügen einen künstlichen Wert erzeugen, z. B. mit der SQL-Funktion %%UUID()%%.   +
 <WRAP center box 80% round><code sql> <WRAP center box 80% round><code sql>
-INSERT INTO favourite_film (ISANtitledirector, released_year, star1+INSERT INTO zieltabelle (spalte1spalte2spalte3
-SELECT UUID(), Series_Title, DirectorReleased_YearStar1 +SELECT quelle_spalte1quelle_spalte2quelle_spalte3 
-FROM imdb_top_1000 +FROM quelle 
-WHERE Released_Year >= 2000;+WHERE bedingung;
 </code></WRAP> </code></WRAP>
  
-> **Hinweis:** Mit der %%WHERE%%-Bedingung können gezielt nur bestimmte Datensätze übernommen werden (z. B. nur Filme ab dem Jahr 2000).   +---
-> **UUID()** erzeugt eine eindeutige ID als Ersatz für das fehlende ISAN. +
- +
- +
-> **Tipps:** +
-> Zahlen/Jahr ohne Anführungszeichen, **Texte in Anführungszeichen**: //'Inception'//+
-> 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, aber dann würden **alle** Datensätze in der ganzen Tabelle überschrieben.+
  
 +**Variante A: Spalten explizit angeben**
 <WRAP center box 80% round><code sql> <WRAP center box 80% round><code sql>
--- Regie-Credit korrigieren (gezielt über Primärschlüssel+INSERT INTO favourite_film (title, director, released_year, star1
-UPDATE favourite_film +VALUES ('Lost in Translation''Sofia Coppola', 2003, 'Scarlett Johansson');
-SET director = 'C. Nolan' +
-WHERE ISAN = '0000-0000-3C2D-0000-0-0000-0000-X';+
 </code></WRAP> </code></WRAP>
  
-**Mehrere Spalten in einem Datensatz auf einmal ändern** +<WRAP center box 80% round> 
-<WRAP center box 80% round><code sql+^ film_id ^ title               ^ director        ^ released_year ^ star1              ^ 
-UPDATE favourite_film +| 1       | Lost in Translation | Sofia Coppola   | 2003          | Scarlett Johansson | 
-SET title = 'Arrival (Extended Cut)', star1 = 'Amy Adams' +</WRAP>
-WHERE ISAN = '0000-0000-4E3F-0000-0-0000-0000-X'; +
-</code></WRAP>+
  
-**Semantische Updates (vorsichtig!)**+**Variante B: Mehrere Zeilen auf einmal**
 <WRAP center box 80% round><code sql> <WRAP center box 80% round><code sql>
--- Alle Filme mit leerem Hauptdarsteller:in mit einem Standardwert füllen (Beispiel+INSERT INTO favourite_film (title, director, released_year, star1
-UPDATE favourite_film +VALUES 
-SET star1 = 'TBD+  ('Inception', 'Christopher Nolan', 2010, 'Leonardo DiCaprio'), 
-WHERE star1 IS NULL;+  ('Arrival', 'Denis Villeneuve', 2016, 'Amy Adams');
 </code></WRAP> </code></WRAP>
  
-**Warnung:** Ohne %%WHERE%% werden **alle Zeilen** geändert. Prüfen Sie Updates immer zuerst mit einem entsprechenden %%SELECT%% (Dry-Run).+<WRAP center box 80% round> 
 +^ film_id ^ title                 ^ director           ^ released_year ^ star1              ^ 
 +| 1       | Lost in Translation   | Sofia Coppola      | 2003          | Scarlett Johansson | 
 +| 2       | Inception             | Christopher Nolan  | 2010          | Leonardo DiCaprio | 
 +| 3       | Arrival               | Denis Villeneuve   | 2016          | Amy Adams         | 
 +</WRAP>
  
-===== DELETE – Daten löschen ===== +**Variante C: INSERT ... SELECT (Daten aus einer anderen Tabelle übernehmen)**   
-Mit dem //DELETE//-Befehl können Datensätze (= Zeilen) aus der Tabelle gelöscht werden.+Mit %%INSERT ... SELECT%% können Datensätze direkt aus einer anderen Tabelle kopiert werden.   
 +Das ist z. B. praktisch, wenn Daten aus //imdb_top_1000// übernommen werden sollen.
  
-**Gezielt löschen (über Primärschlüssel)** 
 <WRAP center box 80% round><code sql> <WRAP center box 80% round><code sql>
-DELETE FROM favourite_film +INSERT INTO favourite_film (title, director, released_year, star1
-WHERE ISAN = '0000-0000-2A1B-0000-0-0000-0000-X'; +SELECT Series_TitleDirectorReleased_YearStar1 
-</code></WRAP> +FROM imdb_top_1000 
- +WHERE Released_Year >= 2000;
-**Mehrere Datensätze in einem Schritt (IN-Liste)** +
-<WRAP center box 80% round><code sql> +
-DELETE FROM favourite_film +
-WHERE ISAN IN ( +
-  '0000-0000-3C2D-0000-0-0000-0000-X', +
-  '0000-0000-4E3F-0000-0-0000-0000-X' +
-); +
-</code></WRAP> +
- +
-**Aufräumen nach Import (z. B. fehlerhafte Jahrgänge)** +
-<WRAP center box 80% round><code sql> +
-DELETE FROM favourite_film +
-WHERE released_year < 1900 OR released_year IS NULL; +
-</code></WRAP> +
- +
-> **Warnung:** //DELETE// ohne %%WHERE%% leert die **gesamte** Tabelle. +
- +
-===== TRUNCATE – Tabelle schnell leeren (ohne WHERE) ===== +
-%%TRUNCATE%% entfernt **alle** Zeilen einer Tabelle **sehr schnell**. Im Unterschied zu //DELETE//: +
-* 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><code sql> +
-TRUNCATE TABLE favourite_film; +
-</code></WRAP> +
- +
-> **Merke:** Nutzen Sie %%TRUNCATE%% nurwenn 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><code sql> +
--- Filme ohne eingetragenen Star +
-SELECT ISANtitle FROM favourite_film +
-WHERE star1 IS NULL; +
- +
--- Filme mit eingetragenem Star +
-SELECT ISANtitlestar1 FROM favourite_film +
-WHERE star1 IS NOT NULL; +
-</code></WRAP> +
- +
-> **Merke:** Vergleiche mit //=// oder //<>// funktionieren bei //NULL// **nicht**. Immer %%IS NULL%% / %%IS NOT NULL%% verwenden. +
- +
-===== 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><code sql> +
--- Dry-Run: Welche Zeilen wären betroffen? +
-SELECT ISAN, title FROM favourite_film +
-WHERE released_year >= 2020;+
 </code></WRAP> </code></WRAP>
  
-Wenn korrekterst dann %%UPDATE%%/%%DELETE%% mit derselben %%WHERE%%-Bedingung ausführen.+> **Hinweis:** Mit %%WHERE%% können gezielt nur bestimmte Datensätze übernommen werden (z. B. ab Jahr 2000).
  
  • modul/m290_guko/learningunits/lu07/theorie/b_sql_dml.1759070097.txt.gz
  • Zuletzt geändert: 2025/09/28 16:34
  • von gkoch