Warum verhindert diese Regel keine doppelten Schlüsselverletzungen?

8

(postgresql) Ich habe versucht, COPY csv-Daten in eine Tabelle zu schreiben, aber ich erhalte doppelte Schlüsselverletzungsfehler, und es gibt keine Möglichkeit, COPY anzuweisen, diese zu ignorieren. Daher habe ich versucht, diese Regel hinzuzufügen:

%Vor%

um das Problem zu umgehen, aber ich bekomme immer noch diese Fehler - irgendwelche Ideen warum?

    
Hendekagon 11.03.2011, 06:13
quelle

2 Antworten

10

Regeln standardmäßig Dinge zur aktuellen Aktion hinzufügen :

  

Grob gesagt bewirkt eine Regel, dass zusätzliche Befehle ausgeführt werden, wenn ein bestimmter Befehl für eine bestimmte Tabelle ausgeführt wird.

Aber eine INSTEAD-Regel erlaubt Ihnen, die Aktion zu ersetzen:

  

Alternativ kann eine INSTEAD-Regel einen gegebenen Befehl durch einen anderen ersetzen oder bewirken, dass ein Befehl überhaupt nicht ausgeführt wird.

Also, ich denke, Sie möchten INSTEAD angeben :

%Vor%

Ohne INSTEAD sagt Ihre Regel im Wesentlichen "mach das INSERT und dann tu nichts", wenn du sagen willst "anstelle des INSERT, tu nichts" und, AFAIK, das DO INSTEAD NOTHING macht das.

Ich bin kein Experte für PostgreSQL-Regeln, aber ich denke, das Hinzufügen von "INSTEAD" sollte funktionieren.

UPDATE : Dank araqnid wissen wir, dass :

  

COPY FROM ruft alle Trigger auf und prüft die Einschränkungen für die Zieltabelle. Es werden jedoch keine Regeln

aufgerufen

Also wird eine Regel in dieser Situation nicht funktionieren. Trigger werden jedoch während COPY FROM ausgelöst, sodass Sie einen Trigger schreiben können, der NULL wenn doppelte Zeilen erkannt wurden:

  

Es kann NULL zurückgeben, um den Vorgang für die aktuelle Zeile zu überspringen. Dies weist den Executor an, die Operation auf Zeilenebene, die den Trigger aufgerufen hat (das Einfügen oder Ändern einer bestimmten Tabellenzeile), nicht auszuführen.

Das heißt, ich denke, Sie wären besser dran mit Araqnids "Laden Sie alles in einen temporären Tisch, reinigen Sie es und kopieren Sie es zum endgültigen Bestimmungsort" wäre eine vernünftigere Lösung für einen Massenladevorgang wie Sie haben.

    
mu is too short 11.03.2011 06:40
quelle
5

COPY FROM ruft keine Regeln auf (http://www.postgresql.org/docs/9.0/interactive/sql-copy.html#AEN58860)

Mein Ansatz wäre, die CSV-Daten in eine temporäre Tabelle zu laden und dann eine INSERT...SELECT -Anweisung zu verwenden, um die Daten in die Zieltabelle zu kopieren, wo sie noch nicht existiert. (Wenn in den CSV-Daten selbst Duplikate vorhanden sind, entfernen Sie diese zuerst aus der temporären Tabelle). Etwas wie:

%Vor%     
araqnid 11.03.2011 11:39
quelle