Zum Inhalt springen
SQL Anfänger 20 min

INSERT - Daten einfügen

Lerne, wie du mit INSERT neue Datensätze in Tabellen einfügst - einzeln, mehrere gleichzeitig und aus anderen Abfragen.

Aktualisiert:

Bisher hast du nur Daten abgefragt. Jetzt lernst du, wie du neue Daten in deine Tabellen einfuegst. INSERT ist der Befehl, mit dem du Datensaetze hinzufuegst.

Grundsyntax von INSERT

INSERT INTO tabellenname (spalte1, spalte2, spalte3)
VALUES (wert1, wert2, wert3);

Einen einzelnen Datensatz einfuegen

-- Einen neuen Kunden einfuegen
INSERT INTO kunden (id, name, email, stadt)
VALUES (6, 'Julia Braun', 'julia@example.com', 'Frankfurt');

Pruefe das Ergebnis:

SELECT * FROM kunden WHERE id = 6;
id | name        | email             | stadt     | registriert_am
---+-------------+-------------------+-----------+---------------
 6 | Julia Braun | julia@example.com | Frankfurt | 2026-03-10

Beachte: registriert_am wurde automatisch auf das aktuelle Datum gesetzt (DEFAULT-Wert).

Spaltennamen angeben

Es ist Best Practice, immer die Spaltennamen anzugeben:

-- GUT: Spalten explizit angeben
INSERT INTO kunden (id, name, email, stadt)
VALUES (7, 'Markus Lang', 'markus@example.com', 'Dresden');

-- SCHLECHT: Ohne Spaltennamen (fehleranfaellig!)
INSERT INTO kunden
VALUES (7, 'Markus Lang', 'markus@example.com', 'Dresden', '2026-03-10');

Warum? Ohne Spaltennamen musst du die exakte Reihenfolge und alle Spalten kennen. Wenn sich die Tabellenstruktur aendert, bricht die Abfrage.

Mehrere Datensaetze gleichzeitig einfuegen

Du kannst mehrere Zeilen auf einmal einfuegen:

INSERT INTO produkte (id, name, preis, kategorie, lagerbestand) VALUES
(7, 'Sandalen Sommer', 34.99, 'Schuhe', 40),
(8, 'Guertel Leder', 24.99, 'Accessoires', 60),
(9, 'Pullover Wool', 59.99, 'Kleidung', 35);

Das ist viel effizienter als drei einzelne INSERT-Befehle, weil die Datenbank nur eine Operation ausfuehren muss.

NULL-Werte und Standardwerte

Spalten weglassen

Wenn du eine Spalte beim INSERT weglaeesst, wird der DEFAULT-Wert oder NULL verwendet:

-- Email und Stadt weglassen -> werden NULL
INSERT INTO kunden (id, name)
VALUES (8, 'Test Kunde');

SELECT * FROM kunden WHERE id = 8;
id | name       | email | stadt | registriert_am
---+------------+-------+-------+---------------
 8 | Test Kunde | NULL  | NULL  | 2026-03-10

DEFAULT-Wert explizit nutzen

INSERT INTO bestellungen (id, kunden_id, betrag, status)
VALUES (6, 1, 49.99, DEFAULT);
-- status wird auf 'offen' gesetzt (der DEFAULT-Wert)

INSERT mit Auto-Increment

In vielen Datenbanken wird die ID automatisch vergeben:

-- PostgreSQL: SERIAL oder GENERATED ALWAYS
CREATE TABLE notizen (
    id SERIAL PRIMARY KEY,
    titel TEXT NOT NULL,
    inhalt TEXT
);

INSERT INTO notizen (titel, inhalt)
VALUES ('Einkaufsliste', 'Milch, Brot, Butter');
-- id wird automatisch vergeben (1, 2, 3, ...)

-- SQLite: INTEGER PRIMARY KEY ist automatisch auto-increment
CREATE TABLE notizen (
    id INTEGER PRIMARY KEY,
    titel TEXT NOT NULL,
    inhalt TEXT
);

INSERT INTO notizen (titel, inhalt)
VALUES ('Einkaufsliste', 'Milch, Brot, Butter');
-- id wird automatisch vergeben

INSERT mit SELECT (Daten kopieren)

Du kannst Daten aus einer Abfrage direkt in eine Tabelle einfuegen:

-- Tabelle fuer Premium-Kunden erstellen
CREATE TABLE premium_kunden (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT,
    gesamtumsatz DECIMAL(10,2)
);

-- Kunden mit mehr als 100 Euro Umsatz als Premium-Kunden einfuegen
INSERT INTO premium_kunden (id, name, email, gesamtumsatz)
SELECT
    k.id,
    k.name,
    k.email,
    SUM(b.betrag)
FROM kunden k
JOIN bestellungen b ON k.id = b.kunden_id
GROUP BY k.id, k.name, k.email
HAVING SUM(b.betrag) > 100;

Daten zwischen Tabellen kopieren

-- Archiv-Tabelle fuer alte Bestellungen
CREATE TABLE bestellungen_archiv (
    id INTEGER,
    kunden_id INTEGER,
    bestelldatum DATE,
    betrag DECIMAL(10,2),
    status TEXT
);

-- Abgeschlossene Bestellungen ins Archiv kopieren
INSERT INTO bestellungen_archiv
SELECT id, kunden_id, bestelldatum, betrag, status
FROM bestellungen
WHERE status = 'abgeschlossen';

INSERT … RETURNING (PostgreSQL)

In PostgreSQL kannst du nach dem INSERT die eingefuegten Daten zurueckbekommen:

-- PostgreSQL: Eingefuegte Daten zurueckgeben
INSERT INTO kunden (id, name, email, stadt)
VALUES (9, 'Nina Fischer', 'nina@example.com', 'Stuttgart')
RETURNING id, name, registriert_am;

Ergebnis:

id | name         | registriert_am
---+--------------+---------------
 9 | Nina Fischer | 2026-03-10

Das ist besonders nuetzlich bei Auto-Increment IDs:

INSERT INTO notizen (titel, inhalt)
VALUES ('Neue Notiz', 'Wichtiger Inhalt')
RETURNING id;
-- Gibt die automatisch vergebene ID zurueck

Konflikte behandeln

INSERT OR IGNORE (SQLite)

-- Ignoriert den Fehler, wenn die ID schon existiert
INSERT OR IGNORE INTO kunden (id, name, email, stadt)
VALUES (1, 'Neuer Name', 'neu@example.com', 'Berlin');

INSERT … ON CONFLICT (PostgreSQL / SQLite)

-- PostgreSQL / SQLite: Upsert (Update bei Konflikt)
INSERT INTO kunden (id, name, email, stadt)
VALUES (1, 'Anna Schmidt-Mueller', 'anna.neu@example.com', 'Berlin')
ON CONFLICT (id) DO UPDATE SET
    name = EXCLUDED.name,
    email = EXCLUDED.email;

Haeufige Fehler

1. Datentyp stimmt nicht

-- FALSCH: Text in eine Zahlenspalte
INSERT INTO produkte (id, name, preis, kategorie, lagerbestand)
VALUES (10, 'Test', 'billig', 'Test', 5);  -- 'billig' ist kein Preis!

-- RICHTIG:
INSERT INTO produkte (id, name, preis, kategorie, lagerbestand)
VALUES (10, 'Test', 9.99, 'Test', 5);

2. NOT NULL verletzt

-- FALSCH: Name ist NOT NULL, darf nicht fehlen
INSERT INTO kunden (id, email)
VALUES (10, 'test@example.com');  -- Fehler: name fehlt!

-- RICHTIG:
INSERT INTO kunden (id, name, email)
VALUES (10, 'Test', 'test@example.com');

3. UNIQUE verletzt

-- FALSCH: Diese E-Mail gibt es schon
INSERT INTO kunden (id, name, email)
VALUES (10, 'Test', 'anna@example.com');  -- Fehler: email muss UNIQUE sein!

4. Fremdschluessel verletzt

-- FALSCH: Kunden-ID 999 existiert nicht
INSERT INTO bestellungen (id, kunden_id, betrag)
VALUES (10, 999, 49.99);  -- Fehler: kunden_id 999 gibt es nicht!

Was kommt als Naechstes?

Im naechsten Tutorial lernst du UPDATE kennen - damit aktualisierst du bestehende Datensaetze.

Zusammenfassung

  • INSERT INTO … VALUES fuegt neue Datensaetze ein
  • Gib immer die Spaltennamen explizit an
  • Du kannst mehrere Zeilen auf einmal einfuegen
  • INSERT … SELECT kopiert Daten aus einer Abfrage
  • RETURNING (PostgreSQL) gibt die eingefuegten Daten zurueck
  • ON CONFLICT behandelt Duplikate (Upsert)
  • Beachte Constraints: NOT NULL, UNIQUE, Fremdschluessel

Uebungen

  1. Einfach: Fuege einen neuen Kunden mit allen Feldern ein.
  2. Mehrere: Fuege 3 neue Produkte in einem einzigen INSERT-Befehl ein.
  3. Mit SELECT: Erstelle eine Tabelle berliner_kunden und kopiere alle Kunden aus Berlin hinein.
  4. Fehlersuche: Warum schlaegt dieser Befehl fehl?
    INSERT INTO bestellungen (id, kunden_id, betrag)
    VALUES (100, 999, 50.00);
  5. Praxis: Fuege eine neue Bestellung fuer einen bestehenden Kunden ein, inklusive Bestellpositionen.
-- Loesung zu Uebung 3:
CREATE TABLE berliner_kunden (
    id INTEGER PRIMARY KEY,
    name TEXT,
    email TEXT
);

INSERT INTO berliner_kunden (id, name, email)
SELECT id, name, email FROM kunden WHERE stadt = 'Berlin';

Pro-Tipp: Teste INSERT-Befehle immer zuerst in einer Testumgebung oder Transaktion. Ein falscher INSERT kann schwer rueckgaengig zu machen sein. In PostgreSQL kannst du BEGIN; vor dem INSERT und ROLLBACK; danach ausfuehren, um die Aenderung rueckgaengig zu machen, wenn etwas nicht stimmt.

Zurück zum SQL Kurs