SQL INSERT, UPDATE, DELETE

6 Kernkonzepte
Die wichtigsten SQL-Befehle zum Ändern von Daten: INSERT · UPDATE · DELETE · Upsert · Transaktionen · Sicherheit Diese Befehle ermöglichen das Einfügen, Aktualisieren und Löschen von Daten in SQL-Datenbanken. Sie sind essenziell für jede Anwendung, die Daten persistiert.

INSERT – Daten einfügen

INSERT INTO tabelle (spalten) VALUES (werte)
INSERT INTO kunden (name, email) VALUES ('Max Mustermann', 'max@example.com');

INSERT fügt neue Datensätze in eine Tabelle ein. Sie können entweder alle Spalten oder nur bestimmte Spalten mit Werten versehen.

INSERT-Varianten

Variante Beschreibung
INSERT INTO tabelle (spalten) VALUES (...) Einfügen mit expliziten Spalten
INSERT INTO tabelle VALUES (...) Alle Spalten in der definierten Reihenfolge
INSERT INTO tabelle (spalten) SELECT ... Einfügen aus SELECT-Abfrage
INSERT INTO tabelle DEFAULT VALUES Einfügen mit Standardwerten
INSERT IGNORE ... MySQL: Duplikate ignorieren
INSERT ... ON CONFLICT PostgreSQL: Bei Konflikt anders handeln
Beispiele
-- Einzelnen Datensatz einfügen
INSERT INTO produkte (name, preis, kategorie)
VALUES ('Laptop', 999.99, 'Elektronik');
-- Mehrere Datensätze auf einmal
INSERT INTO produkte (name, preis, kategorie)
VALUES
('Maus', 29.99, 'Elektronik'),
('Tastatur', 49.99, 'Elektronik');
-- INSERT mit SELECT (Daten kopieren)
INSERT INTO produkte_archiv (name, preis)
SELECT name, preis FROM produkte
WHERE preis > 100;
-- PostgreSQL: INSERT mit RETURNING
INSERT INTO kunden (name, email)
VALUES ('Anna Schmidt', 'anna@example.com')
RETURNING id;
MySQL/Ausgabe:
Query OK, 3 rows affected
Die neue ID bei AUTO_INCREMENT wird über LAST_INSERT_ID() abgerufen
Tipp: Bei INSERT mit vielen Datensätzen kann INSERT INTO ... VALUES (...), (...), ... die Performance erheblich verbessern, da nur ein Befehl an die Datenbank gesendet wird.

UPDATE – Daten aktualisieren

UPDATE tabelle SET spalte = wert WHERE bedingung
UPDATE produkte SET preis = preis * 1.1 WHERE kategorie = 'Elektronik';

UPDATE ändert vorhandene Datensätze. Die WHERE-Klausel ist entscheidend – ohne sie werden alle Datensätze aktualisiert!

UPDATE-Optionen

Option Beschreibung
SET spalte = wert Einzelne Spalte setzen
SET spalte1 = wert1, spalte2 = wert2 Mehrere Spalten gleichzeitig
SET spalte = spalte + 1 Wert basierend auf aktuellem Wert ändern
WHERE EXISTS (SELECT ...) Bedingte Aktualisierung
UPDATE ... ORDER BY ... LIMIT MySQL: Nur bestimmte Zeilen
UPDATE ... RETURNING PostgreSQL: Geänderte Werte zurückgeben
Beispiele
-- Einzelne Spalte aktualisieren
UPDATE kunden
SET email = 'neue.email@example.com'
WHERE id = 1;
-- Mehrere Spalten aktualisieren
UPDATE produkte
SET preis = 1299.99, kategorie = 'Premium'
WHERE id = 5;
-- Preis um 10% erhöhen (alle Elektronik-Artikel)
UPDATE produkte
SET preis = preis * 1.1
WHERE kategorie = 'Elektronik';
-- Komplexe Bedingung mit Subquery
UPDATE produkte
SET bestand = 0
WHERE id IN (
SELECT produkt_id FROM bestellungen
WHERE datum < '2024-01-01'
);
-- PostgreSQL: Geänderte Werte zurückgeben
UPDATE produkte
SET preis = preis * 0.9
WHERE kategorie = 'Aktion'
RETURNING id, name, preis;
⚠️ Warnung: Vergessen Sie niemals die WHERE-Klausel bei UPDATE! UPDATE tabelle SET spalte = wert; aktualisiert alle Zeilen der Tabelle – ein häufiger und gefährlicher Fehler.

DELETE – Daten löschen

DELETE FROM tabelle WHERE bedingung
DELETE FROM produkte WHERE id = 42;

DELETE entfernt Datensätze aus einer Tabelle. Ohne WHERE-Klausel werden alle Datensätze gelöscht. Für das vollständige Leeren einer Tabelle ist TRUNCATE oft effizienter.

DELETE vs TRUNCATE

Merkmal DELETE TRUNCATE
Geschwindigkeit Langsamer (loggt jede Zeile) Sehr schnell (nur Metadaten)
WHERE-Klausel Ja Nein
Transaktionssicher Ja Ja
Auto-Increment-Reset Nein Ja (meistens)
Trigger Ja Nein
Logging Jede Zeile Nur Tabellenstruktur
Beispiele
-- Einzelnen Datensatz löschen
DELETE FROM kunden
WHERE id = 15;
-- Mit Bedingung löschen
DELETE FROM produkte
WHERE bestand = 0 AND kategorie = 'Auslauf';
-- Alle Datensätze löschen (Vorsicht!)
DELETE FROM produkte; -- Alle Zeilen löschen
-- TRUNCATE (schneller, ohne Trigger)
TRUNCATE TABLE produkte;
-- Mit ORDER BY und LIMIT (MySQL)
DELETE FROM logs
ORDER BY datum
LIMIT 100; -- Löscht die 100 ältesten Logs
⚠️ Warnung: DELETE ohne WHERE löscht alle Zeilen einer Tabelle! Verwenden Sie TRUNCATE für eine vollständige Tabellenleerung – es ist schneller und kann in Transaktionen zurückgerollt werden.

Upsert – INSERT oder UPDATE

INSERT ... ON DUPLICATE · ON CONFLICT · MERGE
-- MySQL INSERT INTO produkte (id, name, preis) VALUES (1, 'Laptop', 999.99) ON DUPLICATE KEY UPDATE preis = preis + 100;

Upsert kombiniert INSERT und UPDATE: Wenn der Datensatz bereits existiert, wird er aktualisiert, andernfalls eingefügt. Die Syntax variiert je nach Datenbank.

Beispiele
-- MySQL: ON DUPLICATE KEY UPDATE
INSERT INTO kunden (id, name, email)
VALUES (1, 'Max Mustermann', 'max@example.com')
ON DUPLICATE KEY UPDATE
name = VALUES(name),
email = VALUES(email);
-- PostgreSQL: ON CONFLICT
INSERT INTO kunden (id, name, email)
VALUES (1, 'Max Mustermann', 'max@example.com')
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
email = EXCLUDED.email;
-- SQLite: ON CONFLICT
INSERT OR REPLACE INTO kunden (id, name, email)
VALUES (1, 'Max Mustermann', 'max@example.com');
-- SQL Server: MERGE
MERGE INTO kunden USING (VALUES (1, 'Max Mustermann', 'max@example.com'))
ON (id = id)
WHEN MATCHED THEN UPDATE SET name = name, email = email
WHEN NOT MATCHED THEN INSERT (id, name, email)
VALUES (id, name, email);
Tipp: Upsert ist ideal für synchronisierende Anwendungen, bei denen Sie nicht wissen, ob ein Datensatz bereits existiert. Die PostgreSQL-Variante ON CONFLICT ist besonders flexibel.

Transaktionen – Mehrere Änderungen sicher machen

BEGIN · COMMIT · ROLLBACK · SAVEPOINT
-- Transaktionsblock BEGIN TRANSACTION; UPDATE konten SET saldo = saldo - 100 WHERE id = 1; UPDATE konten SET saldo = saldo + 100 WHERE id = 2; COMMIT;

Transaktionen fassen mehrere Datenbankoperationen zu einer atomaren Einheit zusammen. Entweder werden alle Änderungen übernommen (COMMIT) oder keine (ROLLBACK).

Beispiele
-- Einfache Transaktion
START TRANSACTION;
INSERT INTO bestellungen (kunde_id, datum)
VALUES (1, CURRENT_DATE);
UPDATE produkte SET bestand = bestand - 1
WHERE id = 42;
COMMIT;
-- Mit SAVEPOINT (Teil-Rollback)
START TRANSACTION;
INSERT INTO logs (text) VALUES ('Start');
SAVEPOINT vor_fehlermeldung;
INSERT INTO logs (text) VALUES ('Fehler'); -- Nicht speichern
ROLLBACK TO vor_fehlermeldung;
INSERT INTO logs (text) VALUES ('Erfolg');
COMMIT;
-- Rollback bei Fehler
START TRANSACTION;
DELETE FROM produkte WHERE id = 99;
IF ROW_COUNT() = 0 THEN
ROLLBACK;
ELSE
COMMIT;
END IF;
Tipp: In Transaktionen sollten Sie immer einen ROLLBACK-Plan für Fehlerfälle haben. Viele ORMs und Frameworks übernehmen die Transaktionsverwaltung automatisch.

Sicherheit – Best Practices & Fallstricke

WHERE · Prepared Statements · NOT NULL
-- Vermeiden Sie SQL Injection -- Gefährlich (NIEMALS so!) INSERT INTO kunden (name) VALUES ('$name'); -- Sicher (Prepared Statement) INSERT INTO kunden (name) VALUES (?);

Sicherheit ist bei INSERT, UPDATE und DELETE besonders wichtig. Die folgenden Best Practices schützen Ihre Daten und Ihre Anwendung.

Best Practices

Praxis Beschreibung
Prepared Statements Immer Parameter-Bindings verwenden – nie Benutzereingaben direkt in SQL einbetten
Immer WHERE Niemals UPDATE oder DELETE ohne WHERE-Klausel ausführen
Transaktionen Mehrere zusammenhängende Änderungen in Transaktionen ausführen
Backups Regelmäßige Backups vor größeren Datenänderungen
Berechtigungen Nur minimale Rechte für die Anwendungsdatenbank (z.B. kein DROP)
Constraints NOT NULL, UNIQUE, FOREIGN KEY – soweit wie möglich nutzen
Validierung Daten vor dem INSERT/UPDATE auf korrekte Formate prüfen
Beispiele
-- Prepared Statement (PHP PDO)
$stmt = $pdo->prepare('INSERT INTO kunden (name, email) VALUES (?, ?)');
$stmt->execute([$_POST['name'], $_POST['email']]);
-- Prüfung vor UPDATE
-- Erst prüfen, ob der Datensatz existiert
SELECT id FROM kunden WHERE id = ?;
-- Wenn ja: UPDATE, sonst INSERT oder Fehler
-- Soft Delete (statt DELETE)
UPDATE kunden SET aktiv = 0, geloescht_am = CURRENT_TIMESTAMP
WHERE id = ?;
-- Prüfung vor DELETE
-- Referenzielle Integrität prüfen (z.B. keine offenen Bestellungen)
SELECT * FROM bestellungen WHERE kunde_id = ? LIMIT 1;
-- Wenn keine Bestellungen: DELETE möglich
⚠️ Kritisch: SQL Injection ist eine der häufigsten Sicherheitslücken. Verwenden Sie immer Prepared Statements oder ORM-Methoden, die Parameter-Bindings unterstützen. Konkatenieren Sie niemals Benutzereingaben direkt in SQL-Strings!

Data Manipulation Language (DML) im Überblick

INSERT Daten einfügen
Neue Zeilen
UPDATE Daten aktualisieren
Vorhandene Zeilen ändern
DELETE Daten löschen
Zeilen entfernen
MERGE Upsert
INSERT oder UPDATE
TRANSACTION Atomare Einheit
COMMIT / ROLLBACK
TRUNCATE Alle Zeilen löschen
Schnell, ohne Trigger

Quick Summary

INSERT
Daten einfügen
UPDATE
Daten aktualisieren
DELETE
Daten löschen
Upsert
Einfügen oder aktualisieren
COMMIT
Transaktion abschließen
Prepared
SQL Injection vermeiden
INSERT INTO kunden (name, email) VALUES (?, ?); · UPDATE produkte SET preis = preis * 1.1 WHERE kategorie = 'Elektronik';