Ich habe eine PostgreSQL 9-Datenbank, die automatisch inkrementierende Ganzzahlen als Primärschlüssel verwendet. Ich möchte einige Zeilen in einer Tabelle kopieren (basierend auf einigen Filterkriterien), während ich einen oder zwei Werte ändere, dh alle Spaltenwerte kopieren, mit Ausnahme der ID (die automatisch generiert wird) und möglicherweise einer anderen Spalte.
Ich möchte aber auch die Zuordnung von alten zu neuen IDs bekommen. Gibt es einen besseren Weg, dies zu tun, dann nur nach den Zeilen zu suchen, die zuerst kopiert werden sollen, und dann neue Zeilen nacheinander einzufügen?
Im Wesentlichen möchte ich so etwas tun:
%Vor% Das scheitert jedoch mit ERROR: missing FROM-clause entry for table "old"
und ich kann sehen, warum: Postgres muss zuerst SELECT ausführen und dann einfügen und die RETURNING
-Klauseln haben nur Zugriff auf die neu eingefügte Zeile.
RETURNING kann nur auf die Spalten in der letzten eingefügten Zeile verweisen. Auf diese Weise kann nicht auf die ID "OLD" verwiesen werden, es sei denn, es gibt eine Spalte in der Tabelle, die sowohl die ID als auch die neue ID enthält.
Versuchen Sie, das auszuführen, was funktionieren sollte, und zeigen Sie alle möglichen Werte an, die Sie über RETURNING erhalten können:
%Vor%Sie erhalten nicht das gewünschte Verhalten, sollten aber besser veranschaulichen, wie RETURNING funktioniert.
Dies kann mit Hilfe von Datenmodifizierungs-CTEs (Postgres 9.1 + ) erfolgen:
%Vor%SQL Fiddle Demonstration.
Dies beruht auf dem nicht dokumentierten Implementierungsdetail, dass Zeilen aus einem SELECT
in der angegebenen Reihenfolge eingefügt werden (und in der angegebenen Reihenfolge zurückgegeben werden). Es funktioniert in allen aktuellen Versionen von Postgres und wird nicht kaputt gehen. Verwandt:
Fensterfunktionen sind in der RETURNING
-Klausel nicht erlaubt, daher gebe ich row_number()
in einer anderen Unterabfrage an.
Weitere Erklärung in dieser verwandten späteren Antwort:
'alt' ist ein reserviertes Wort, das vom Regelüberschreibsystem verwendet wird. [Ich nehme an, dass dieses Abfragefragment nicht Teil einer Regel ist; in diesem Fall hättest du die Frage anders formuliert]
fügen Sie vor dem Einfügen ein weiteres Update hinzu, um ein anderes Feld zu ändern
%Vor%Tags und Links sql postgresql sql-insert sql-returning