SQL INSERT IF NOT EXISTS --> erster Durchlauf

johamu

Neuer Benutzer
Beiträge
4
Hallo,
vermutlich nur eine Kleinigkeit, aber
1) Ich habe eine Sourcetabelle, einfaches Beispiel:
Source-Tab, eine Spalte mit int, enthält die Werte 1,2,3,2,

2) Ich habe eine leere Zieltabelle, ebenfalls nur eine Spalte von Typ int

Die Spalte soll in beiden Tabelle A heißen.

Ich möchte in die Ziel-Tabelle nur jene Werte aus Source einfügen, die noch nicht enthalten sind.

INSERT INTO Dest (A)
SELECT A FROM Source
WHERE not exists (SELECT A FROM Dest D WHERE D.A = A)

Wenn die Zieltabelle leer ist, wird mir die "2" doppelt eingefügt.
Bei einem zweiten Durchlauf funktioniert es wie erartet.

Es scheint so, als würde das "WHERE not exists ..." nur jene Einträge berücksichtigen, die schon in der Datenbank sind und jene, die sozusagen unterwegs sind, nicht beachten .

In meinem Fall kann ich das Problem einfach mit einem SELECT DISTINCT lösen.

Gibt es auch andere Lösungsmöglichkeiten?

Danke!!
 
Werbung:
Nun ja, wenn Du da in dest(a) nur unique Werte haben willst kannst das auch definieren, in Deinem Beispiel:

Code:
test=*# alter table dest add constraint a_unique unique(a);
ALTER TABLE
test=*# insert into dest(a) select a from source where not exists(select distinct a from dest d where d.a=a);
ERROR:  duplicate key value violates unique constraint "a_unique"
DETAIL:  Key (a)=(2) already exists.
test=*# insert into dest(a) select distinct a from source where not exists(select distinct a from dest d where d.a=a);
INSERT 0 3
test=*#

Dann würde der erste Versuch scheitern, weil 2 doppelt eingefügt werden würde. Hilft das weiter?
 
Danke für die Antwort.

Die Lösung stellt die Datenintegrität sicher aber ich müsste dann auch irgendwie den Fehler abfangen, denn es soll nicht abgebrochen werden sondern mit dem Rest fortgesetzt werden (d.h. alle noch nicht existierenden sollen eingefügt werden, die existierenden sollen ignoriert werden).

Schöne Grüße, johamu
 
Genau, darum eben DISTINCT und das vorgeschlagene UNIQUE ist sozusagen die Absicherung, die Alarmanlage.

Ich habe nur wegen der Performance von DISTINCT bedenken und wollte es mit eventuellen vorhanden Alternativen (die ich nicht kenne) vergleichen.
 
Mit Indizes experimentiere ich gerade - Datensatzanzahl: 100.000 aufwärts
In so einem frühen Stadium interessiere ich mich halt auch für alternative konzeptuelle Ansätze ...
 
Werbung:
DISTINCT ist ja auch nur ein GROUP BY, die beiden sollten sich von der Performance her nicht unterscheiden aber probieren kannst du es mal. Statt mit WHERE NOT EXISTS solltest du mit EXCEPT arbeiten.
Code:
INSERT INTO Dest (A)
SELECT DISTINCT A FROM Source
EXCEPT
SELECT A FROM Dest
 
Zurück
Oben