Ich versuche, doppelte INSERTs in einer Tabelle zu erkennen und stillschweigend zu verwerfen, und wenn ein Duplikat erkannt wurde, gebe die ID (Primärschlüssel) des vorhandenen Datensatzes zurück. Andernfalls fügen Sie den Datensatz ein und geben Sie die neue ID zurück.Rails Postgres Einfügen von doppelten Zeilenprüfungsproblemen
Ich kann dies entweder mit einer Regel oder einem Trigger, aber beide haben Nachteile. Hier ist ein Beispiel für meine Regel:
Testen Sie dies in einer SQL-Konsole oder psql mit einem INSERT funktioniert gut. Wenn es einen Duplikat gibt, wird die ID des ersten existierenden Datensatzes zurückgegeben und nicht der INSERT. Ansonsten wird es mit dem INSERT weitergehen. In Rails schlägt es jedoch fehl und gibt diesen Fehler zurück:
FEHLER: INSERT RETURNING für Relation "territory_products" kann nicht ausgeführt werden TIPP: Sie benötigen eine bedingte ON INSERT DO INSTEAD-Regel mit einer RETURNING-Klausel.
zu einem TRIGGER bewegen, versuche ich dies:
CREATE OR REPLACE Function territory_products_ignore_dups() Returns Trigger
As $$
Begin
If Exists (
Select id From territory_products tp
Where tp.territory_id = NEW.territory_id And tp.product_id = NEW.product_id
) Then
Return NULL;
End If;
Return NEW;
End;
$$ Language plpgsql;
Create Trigger territory_products_ignore_dups
Before Insert On territory_products
For Each Row
Execute Procedure territory_products_ignore_dups();
Dies auch gut funktioniert, außer, dass ich nicht bekommen kann die bestehende ID, wegen der Rückkehr NULL zurück (was erforderlich ist, um nicht zuzulassen der INSERT).
Kann jemand eines dieser Probleme lösen, so bekomme ich das Ergebnis, das ich suche? (Verwerfen Sie z. B. die INSERT-Datei im Falle eines Duplikats und geben Sie die ID des vorhandenen Datensatzes zurück. Wenn die INSERT-Operation erfolgreich ist, geben Sie die ID des neuen Datensatzes zurück).
Warum nicht einfach eine Einzigartigkeit Validierung in Rails erstellen und eine Verbindung Index in PG hinzufügen gegen Rennbedingungen zu schützen? – max
Mach was max gesagt. Erzwingt nur eindeutige Datensätze und Sie können nur eine Aktualisierung durchführen, wenn der Datensatz existiert. – bkunzi01
Eine Eindeutigkeitsüberprüfung ist in Situationen mit hohem Datenaufkommen nicht vollsicher, da Rails im Grunde nur einen SELECT ausführt, um die Überprüfung vor dem INSERT durchzuführen. Außerdem werden wir manchmal Updateskripte auf der Datenbank ausführen, also möchten wir, dass die Überprüfung dort ist, aber ohne Ausnahmen überall zu werfen. – BeachBum