©Sergey Emelyanov 2025 | Alle Rechte vorbehalten
In diesem Artikel betrachten wir detailliert den Prozess des Dateneinfügens in PostgreSQL und zeigen, wie Sie Fehler vermeiden können, wenn doppelte Daten vorhanden sind. Alle Beispiele werden an einer Testdatenbank durchgeführt – den Dump dieser Datenbank finden Sie unter:
https://www.postgresqltutorial.com/postgresql-sample-database/
INSERT INTO customer (active, activebool, address_id, create_date, email, first_name, last_name, last_update, store_id)
VALUES (1, default, 10, default, 'test2@test.com', 'Andrey', 'Vasilyev', default, 2);
Möchten Sie mehrere Datensätze in einem Schritt einfügen, verwenden Sie diesen Syntax:
INSERT INTO customer (active, activebool, address_id, create_date, email, first_name, last_name, last_update, store_id)
VALUES (1, default, 10, default, 'test2@test.com', 'Andrey', 'Vasilyev', default, 2),
(1, default, 11, default, 'test4@test.com', 'Ivan', 'Ivanov', default, 2)
RETURNING customer_id;
Beachten Sie den Zusatz RETURNING customer_id – dieser Ausdruck liefert nach dem Einfügen die IDs der neu erzeugten Datensätze zurück.
ALTER TABLE customer ADD CONSTRAINT email_unique UNIQUE (email);
Nach dieser Änderung wird PostgreSQL verhindern, dass zwei Datensätze dieselbe E-Mail-Adresse enthalten.
INSERT INTO customer (active, activebool, address_id, create_date, email, first_name, last_name, last_update, store_id)
SELECT active, activebool, address_id, create_date, email, first_name, last_name, last_update, store_id
FROM customer
WHERE customer_id = 10
RETURNING customer_id;
Da der ausgewählte Datensatz bereits eine E-Mail enthält, die im Unique-Constraint definiert ist, liefert diese Abfrage den Fehler: ERROR: duplicate key value violates unique constraint "email_unique"
SELECT count(1) FROM customer WHERE email = 'test2@test.com';
Diese Methode ist allerdings etwas umständlich, denn es gibt eine elegantere Lösung.
a) Konflikt überspringen
Möchten Sie bei einem Konflikt einfach nichts tun, verwenden Sie:
INSERT INTO customer (active, activebool, address_id, create_date, email, first_name, last_name, last_update, store_id)
VALUES (1, default, 19, default, 'helen.harris@sakilacustomer.org', 'Helen', 'Harris', default, 1)
ON CONFLICT DO NOTHING;
Dieser Befehl wirft keinen Fehler, selbst wenn bereits ein Datensatz mit der E-Mail „helen.harris@sakilacustomer.org“ existiert.
b) Datensatz aktualisieren
Angenommen, der Benutzer Helen zieht um und Sie möchten den vorhandenen Datensatz aktualisieren (z. B. neue Adresse, neuer Vor- und Nachname). Dann hilft folgender Befehl weiter:
INSERT INTO customer (active, activebool, address_id, create_date, email, first_name, last_name, last_update, store_id)
VALUES (1, default, 20, default, 'helen.harris@sakilacustomer.org', 'Helena', 'Harry', default, 1)
ON CONFLICT (email) DO UPDATE
SET first_name = EXCLUDED.first_name,
last_name = EXCLUDED.last_name,
address_id = EXCLUDED.address_id
RETURNING customer_id;
Hier wird der Konflikt anhand des Feldes email erkannt. Das Schlüsselwort EXCLUDED verweist auf die neuen, im INSERT-Befehl angegebenen Werte. Bei einem Konflikt übernimmt PostgreSQL die neuen Werte für first_name, last_name und address_id und aktualisiert damit den bestehenden Datensatz. Mit RETURNING customer_id erhalten Sie abschließend die ID des betroffenen Kunden.
Fazit
Unter Verwendung der ON CONFLICT-Klausel können Sie in PostgreSQL Daten problemlos einfügen, ohne durch Duplicate-Key-Fehler behindert zu werden. Diese Methode bietet nicht nur eine elegante Fehlerbehandlung, sondern ermöglicht auch die Aktualisierung bestehender Datensätze, sollte sich etwa eine Information ändern. So bleiben Ihre Daten konsistent und die Einfügeoperationen effizient.
©Sergey Emelyanov 2025 | Alle Rechte vorbehalten