CodeGym /Kurse /SQL SELF /Fehlerbehandlung beim Laden von Daten ( ON CONFLIC...

Fehlerbehandlung beim Laden von Daten ( ON CONFLICT)

SQL SELF
Level 23 , Lektion 3
Verfügbar

Willkommen im Herzen der dramatischen Massendaten-Import-Szenarien! Heute lernst du, wie du mit Fehlern beim Laden von Daten mit der ON CONFLICT-Klausel clever umgehst. Das ist wie Autopilot im Flugzeug: Selbst wenn was schiefgeht, weißt du, wie du einen Crash vermeidest. Los geht’s mit den PostgreSQL-Tricks!

Niemand mag Überraschungen – besonders nicht, wenn Daten sich weigern, geladen zu werden! Beim Massendatenimport kannst du auf ein paar typische Probleme stoßen:

  • Daten-Duplikate. Zum Beispiel, wenn die Tabelle ein UNIQUE-Constraint hat und deine Datei voller Wiederholungen steckt.
  • Konflikte mit Constraints. Versuch mal, einen leeren Wert in eine Spalte mit NOT NULL-Constraint zu laden. Ergebnis? Fehler. PostgreSQL bleibt da immer streng.
  • Doppelte Primärinformationen. Die Tabelle kann schon Daten mit denselben IDs enthalten wie deine CSV-Datei.

Schauen wir uns an, wie du diese "Stolpersteine" mit ON CONFLICT umschiffst.

ON CONFLICT zur Fehlerbehandlung nutzen

Mit der ON CONFLICT-Klausel kannst du angeben, was bei einem Konflikt mit Constraints (wie UNIQUE oder PRIMARY KEY) passieren soll. PostgreSQL gibt dir die Wahl: Entweder du aktualisierst bestehende Daten oder ignorierst die Konfliktzeile einfach.

So sieht der grundlegende Syntax von ON CONFLICT aus:

INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...)
ON CONFLICT (conflict_target)
DO UPDATE SET column1 = new_value1, column2 = new_value2;

Du kannst DO UPDATE auch durch DO NOTHING ersetzen, wenn du den Konflikt einfach ignorieren willst.

Beispiel: Daten bei Konflikt aktualisieren

Nehmen wir an, wir haben eine Tabelle students:

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    age INT
);

Jetzt wollen wir neue Daten laden, aber einige davon gibt es schon in der Datenbank:

INSERT INTO students (id, name, age)
VALUES 
    (1, 'Peter', 22),  -- Dieser Student ist schon da
    (2, 'Anna', 20),  -- Neuer Student
    (3, 'Mal', 25) -- Neuer Student
ON CONFLICT (id) DO UPDATE SET 
    name = EXCLUDED.name, 
    age = EXCLUDED.age;

In diesem Beispiel werden die Daten eines Studenten mit einer bereits vorhandenen ID aktualisiert:

ON CONFLICT (id) DO UPDATE SET
    name = EXCLUDED.name, 
    age = EXCLUDED.age;

Achte auf das magische Wort EXCLUDED. Das steht für "die Werte, die du einfügen wolltest, die aber wegen eines Konflikts ausgeschlossen wurden".

Ergebnis:

  • Der Student mit id = 1 bekommt seine Daten (Name und Alter) aktualisiert.
  • Die Studenten mit id = 2 und id = 3 werden neu in die Tabelle eingefügt.

Beispiel: Konflikte ignorieren

Wenn du keine Daten aktualisieren, sondern nur die Konfliktzeilen ignorieren willst, nutze DO NOTHING:

INSERT INTO students (id, name, age)
VALUES 
    (1, 'Peter', 22),  -- Dieser Student ist schon da
    (2, 'Anna', 20),  -- Neuer Student
    (3, 'Mal', 25) -- Neuer Student
ON CONFLICT (id) DO NOTHING;

Jetzt werden die Konfliktzeilen einfach nicht eingefügt und der Rest landet entspannt in deiner Datenbank.

Fehler protokollieren

Manchmal reicht Ignorieren oder Aktualisieren nicht. Zum Beispiel, wenn du Konflikte für spätere Analysen speichern willst. Wir können eine spezielle Tabelle fürs Fehler-Logging anlegen:

CREATE TABLE conflict_log (
    conflict_time TIMESTAMP DEFAULT NOW(),
    id INT,
    name TEXT,
    age INT,
    conflict_reason TEXT
);

Jetzt bauen wir Fehlerbehandlung mit Logging ein:

INSERT INTO students (id, name, age)
VALUES 
    (1, 'Peter', 22), 
    (2, 'Anna', 20), 
    (3, 'Mal', 25)
ON CONFLICT (id) DO UPDATE SET 
    name = EXCLUDED.name, 
    age = EXCLUDED.age
RETURNING EXCLUDED.id, EXCLUDED.name, EXCLUDED.age
INTO conflict_log;

Das letzte Beispiel funktioniert nur innerhalb von Stored Procedures. Wie das genau läuft, erfährst du, wenn wir PL-SQL behandeln. Ich greife hier ein bisschen vor, wollte dir aber noch eine Möglichkeit zeigen, wie du Konflikte beim Laden von Daten lösen kannst: Logging aller problematischen Zeilen.

Jetzt kannst du die Gründe für Konflikte analysieren. Diese Technik ist besonders nützlich in komplexen Systemen, wo es wichtig ist, "Spuren" bei Massendatenimporten zu behalten.

Praktisches Beispiel

Lass uns alles Gelernte in einer einfachen Aufgabe zusammenbringen. Stell dir vor, du hast eine CSV-Datei mit Studenten-Updates, die du in die Tabelle laden willst:

Datei students_update.csv

id name age
1 Otto 23
2 Anna 21
4 Wally 30

Daten laden und Konflikte behandeln

  1. Erstmal erstellen wir eine temporäre Tabelle tmp_students:
CREATE TEMP TABLE tmp_students (
  id   INTEGER,
  name TEXT,
  age  INTEGER
);
  1. Daten aus der Datei mit \COPY laden:
\COPY tmp_students FROM 'students_update.csv' DELIMITER ',' CSV HEADER
  1. Daten aus der temporären Tabelle in die permanente Tabelle mit INSERT ON CONFLICT einfügen:
INSERT INTO students (id, name, age)
SELECT id, name, age FROM tmp_students
ON CONFLICT (id) DO UPDATE
  SET name = EXCLUDED.name,
      age = EXCLUDED.age;

Jetzt sind alle Daten, inklusive Updates (Zeile mit id = 1), erfolgreich geladen.

Typische Fehler und wie du sie vermeidest

Fehler passieren selbst den erfahrensten Programmierern, aber wenn du weißt, wie du sie umgehst, sparst du dir Stunden (vielleicht sogar Tage) an Nerven.

  • Konflikt mit UNIQUE-Constraint. Achte darauf, dass du das richtige Feld in ON CONFLICT angibst. Wenn du z.B. den falschen Schlüssel (id statt email) nimmst, sagt PostgreSQL einfach "tschüss" zu deiner Anfrage.
  • Falsche Nutzung von EXCLUDED. Dieser Alias bezieht sich nur auf Werte aus der aktuellen Anfrage. Versuch nicht, ihn in anderen Kontexten zu verwenden.
  • Spalten vergessen. Achte darauf, dass alle Spalten, die du in SET angibst, auch wirklich in der Tabelle existieren. Wenn du z.B. SET non_existing_column = 'value' schreibst, gibt’s einen Fehler.

Mit ON CONFLICT wird der Massendatenimport in PostgreSQL flexibel und sicher. Du kannst nicht nur verhindern, dass Anfragen wegen Konflikten scheitern, sondern auch steuern, wie deine Daten verarbeitet werden. Deine User (und Server!) werden es dir danken.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION