2017-07-09 3 views
2

Manchmal möchten Sie vielleicht verschieben Sie einige Daten von einer Spalte in eine andere Spalte. Durch Verschieben (im Gegensatz zu Kopieren), meine ich, dass die neue Spalte ursprünglich Null vor dem Ausführen der Operation war, und die alte Spalte sollte nach dem Ausführen der Operation auf null festgelegt werden.Verschieben von Daten von einer Spalte in eine andere in PostgreSQL

Ich habe eine Tabelle als solche definiert:

CREATE TABLE photos(id BIGSERIAL PRIMARY KEY, photo1 BYTEA, photo2 BYTEA);

Angenommen, ein Eintrag in der Tabelle ist, wo photo1 einige Daten enthält, und photo2NULL ist. Ich möchte eine UPDATE Anfrage machen, dass photo1 wird NULL und photo2 enthält die Daten, die ursprünglich in photo1 war.

ich geben Sie den folgenden SQL-Befehl (WHERE Klausel der Kürze halber weggelassen):

UPDATE photos SET photo2 = photo1, photo1 = NULL;

Es scheint zu funktionieren.

Ich versuchte es auch auf diese Weise:

UPDATE photos SET photo1 = NULL, photo2 = photo1;

Es scheint auch zu funktionieren.

Aber ist es garantiert zu arbeiten? Konnte speziell photo1 auf NULLgesetzt werden, bevorphoto2 auf photo1 gesetzt wird, wodurch mich am Ende mit NULL in beiden Spalten enden?

Als Nebenwirkung dieser Standard UPDATE Syntax scheint ineffizient, wenn meine BYTEA s groß sind, als photo2 Byte-für-Byte kopiert werden muss von photo1, wenn ein einfacher Austausch von Zeigern könnte reicht haben. Vielleicht gibt es einen effizienteren Weg, von dem ich nichts weiß?

+0

Ja, dies funktioniert garantiert (und wird vom SQL-Standard benötigt) –

Antwort

3

Dies ist definitiv sicher.

Spaltenverweise im UPDATE beziehen sich auf die alten Spalten, nicht die neuen Werte. Es gibt tatsächlich keine Möglichkeit, einen berechneten neuen Wert aus einer anderen Spalte zu referenzieren.

Siehe z.B.

CREATE TABLE x (a integer, b integer); 
INSERT INTO x (a,b) VALUES (1,1), (2,2); 

UPDATE x SET a = a + 1, b = a + b; 

Ergebnisse in

test=> SELECT * FROM x; 
a | b 
---+--- 
2 | 2 
3 | 4 

... und die Reihenfolge der Zuweisungen ist nicht signifikant. Wenn Sie versuchen, einen Wert zu multiplizieren zuweisen, werden Sie

test=> UPDATE x SET a = a + 1, a = a + 1; 
ERROR: multiple assignments to same column "a" 

bekommen, weil es keinen Sinn macht, auf die gleiche Spalte mehrere Male, da zugewiesen werden, dass beide Ausdrücke die alten Tupel Werte verweisen und um nicht signifikant .

Um jedoch eine vollständige Tabelle in diesem Fall neu zu schreiben, würde ich nur ALTER TABLE ... ALTER COLUMN ... RENAME ... dann CREATE die neue Spalte mit dem alten Namen.

+0

Danke, das sollte meine Ängste vor nicht-deterministischem Verhalten zerstreuen. Bezüglich der Spaltenumbenennung kann ich das nicht tun, weil es keine vollständige Neuschreibung der Tabelle ist. Als ich "WHERE" -Klausel zur Abkürzung vermerkte, meine ich, dass es eine "WHERE" -Klausel in der "UPDATE" -Anweisung gibt, die ich weggelassen habe (und daher sind nicht alle Zeilen betroffen). Vielleicht war mir das nicht klar. – Bernard

+0

Ich stimme dem Kommentar von @ Jacobm001 zu dem jetzt gelöschten Post zu, dass das, was Sie tun, ein bisschen seltsam ist, wenn es darum geht, Daten von Spalte zu Spalte zu verschieben. Ich würde stattdessen zu einem Beistelltisch normalisieren und den referenzierenden FK auf das neue Foto aktualisieren. –

+0

Ich habe den Kommentar nicht gesehen, bevor der Beitrag gelöscht wurde und ich nicht genügend Reputation habe, um gelöschte Kommentare zu sehen. Könnten Sie bitte erläutern, warum es besser wäre, einen Beistelltisch zu verwenden, und ob ich dies nur für große Datenmengen (wie BYTEA) oder für kleine Textfelder tun sollte? – Bernard

Verwandte Themen