Datenübertragung mittels update

Guten Tag,

folgendes Problem: ich möchte mittels update und select aus einer Tabelle Daten in eine andere überführen.

Tabelle A und B sind strukturgleich. Die Felder 1 und 2 sind in beiden Tabellen die Primärschlüssel. In Tabelle B stehen Informationen in Feld 3, die ich in das entsprechende Feld in Tabelle A überspielen möchte.

update Tabelle-A set Feld-A3 = (select Feld-B3 from Tabelle-B where (Tabelle-A.Feld-A1,Tabelle-A.Feld-A2) = (Tabelle-B.Feld-B1, Tabelle-B.Feld-B2));

Diese Anweisung läuft ohne Fehlermeldung durch, aber es paasiert nichts: das Feld 3 in Tabelle A enthält immer noch lauter NULLen.

Wenn ich die select-Anweisung herausschäle:

select Feld-B3 from Tabelle-B where (Tabelle-A.Feld-A1,Tabelle-A.Feld-A2) = (Tabelle-B.Feld-B1, Tabelle-B.Feld-B2)

dann kommt die Fehlermeldung

FEHLER: fehlender Eintrag in FROM-Klausel für Tabelle …

Diese Fehlermeldung habe ich in diesem Forum schon mal gefunden:

http://www.pg-forum.de/sql/2648-update-mit-dem-ergebnis-eines-subselects.html

Leider bin ich mit den Atworten dort nicht klargekommen. Eine kleine Recherche im Internet ergab als Hinweis:

“Dieser Fehler tritt auf wenn die Einstellung “Freitextfeld” vom Administrator noch nicht gesetzt ist. Durch einen Fehler in der Version 1.1.16 wird beim Anlegen eines Gastes ein ungültiges SQL generiert. Zur Behebung dieses Fehlers wählen Sie als Administrator unter Einstellungen bitte ein gültiges “Freitextfeld” aus”

Leider kann ich auch mit diesem Hinweis nichts anfangen.

Ich arbeite in meiner Datenbank mit root-Rechten und Postgresql 8.1.5. Was mich an der Sache so fuchsig macht, ist, dass ich früher schon mal solche updates gemacht habe. Letztlich habe ich meine alten Skripte genommen, die ich stets aufhebe und nur Tabellen- und Spaltennamen geändert. Ich verstehe nicht, warum es diesmal nicht klappt und wäre für Hinweise dankbar.

Eremit

Das ist ein Syntaxfehler. Warum schreibst Du irgendwas, aber nicht das, was Du wirklich machst?


Diese Anweisung läuft ohne Fehlermeldung durch, aber es paasiert nichts: das Feld 3 in Tabelle A enthält immer noch lauter NULLen.


test=# select * from table_a;
 feld1 | feld2 | feld3
-------+-------+-------
     1 |     2 |     3
    10 |    20 |    30
(2 rows)

test=*# select * from table_b;
 feld1 | feld2 | feld3
-------+-------+-------
     1 |     2 |
    10 |    20 |
(2 rows)

test=*# update table_b b set feld3 = a.feld3 from table_a a where  ((a.feld1,a.feld2)=(b.feld1,b.feld2)) and b.feld3 is null;
UPDATE 2
test=*# select * from table_b;
 feld1 | feld2 | feld3
-------+-------+-------
     1 |     2 |     3
    10 |    20 |    30
(2 rows)



Leider bin ich mit den Atworten dort nicht klargekommen. Eine kleine Recherche im Internet ergab als Hinweis:

“Dieser Fehler tritt auf wenn die Einstellung “Freitextfeld” vom Administrator noch nicht gesetzt ist. Durch einen Fehler in der Version 1.1.16 wird beim Anlegen eines Gastes ein ungültiges SQL generiert. Zur Behebung dieses Fehlers wählen Sie als Administrator unter Einstellungen bitte ein gültiges “Freitextfeld” aus”

Leider kann ich auch mit diesem Hinweis nichts anfangen.

Ich auch nicht. Vermutlich ein Problem mit Äpfeln und Birnen.


Ich arbeite in meiner Datenbank mit root-Rechten und Postgresql 8.1.5.

Don’t work as root. Und wenn doch, dann mache ein Update.


Andreas

Danke für die schnelle Antwort. Ich habe Deinen Code bei mir angewendet. Bei dem Alias b für table_b meldet mein System einen Syntaxfehler. Kann das etwas mit meiner Postgresql-Version zu tun haben? Ich habe bisher nicht mit Aliasen gearbeitet.

Ich arbeite zwar als root in der Datenbank, kann aber kurzfristig kein upgrade durchführen.

Mein Problem habe ich allgemeiner formuliert, weil ich freundlich sein wollte. Die Feldnamen sind etwas länglich.

Was ich auch einfach nicht blicke, ist, warum diese Syntax bei mir mit anderen Tabellen schon gelaufen ist.
update table_a set feld_a3 = (select b3 from table_b where (table_a.feld_a1,table_a.feld_a2) = (table_b.feld_b1, table_b.feld_b2));

Eremit

Funktioniert mit 8.1 und 8.3. Vermutlich also PEBKAC.

Ich arbeite zwar als root in der Datenbank, kann aber kurzfristig kein upgrade durchführen.

Als root zu arbeiten ist ein Indiz für Leichtsinn und dem Nichtverstehen des User-Konzeptes Deines OS.

Mein Problem habe ich allgemeiner formuliert, weil ich freundlich sein wollte. Die Feldnamen sind etwas länglich.

Was ich auch einfach nicht blicke, ist, warum diese Syntax bei mir mit anderen Tabellen schon gelaufen ist.
update table_a set feld_a3 = (select b3 from table_b where (table_a.feld_a1,table_a.feld_a2) = (table_b.feld_b1, table_b.feld_b2));

Eremit

Copy&Paste Deines Befehls obens lief nach Anpassung der Spaltennamen bei mir.

Andreas

Ich habe eine neue kleine Testtabelle aus drei Spalten erstellt. Die ersten beiden Spalten sind pk. Dann habe ich zwei Datensätze eingefügt. Anschließend habe ich mit der oben angegebenen Syntax die dritte Spalte mit einer anderen Tabelle per update abgeglichen --> funktioniert.

Mit anderen Worten: dieses Update mit dieser Syntax läuft mit einer Tabelle und mit einer anderen nicht.

Alle angegebenen Tabellen haben gleiche Eigentümer und befinden sich in derselben Domäne. Die pk (je zwei Spalten) sind alle indentisch (auch bei der Testtabelle): gleiche Feldtypen, gleicher Inhalt.

Ich werde mir nun so helfen, dass ich die ursprüngliche Tabelle, die ich auf zwei Tabellen aufspalten will, noch mal nehme und von vorne anfange. Anscheind geht das ja. Nur verstehen kann ich das nicht. Vielleicht liegt es auch an der Hitze.

Eremit

Wie wäre es, wenn du mal einen pg_dump deines Problems hier postest?

Entschuldigung: was ist ein pg_dump?

Ich bin aber jetzt weiter. Ich habe alle seit Sontag neu generierten Tabellen gelöscht und die Arbeit wiederholt. Das update funktioniert nun - dieselben sql-statements, die gestern nicht funktioniert haben, gehen nun mit neu generierten Tabellen, die genauso aufgebaut sind, wie die Gelöschten.

Zwar habe ich mein Problem damit gelöst, aber nicht verstanden. Deswegen werde ich auch gerne den dump liefern, wenn Du mir erklärst, was das ist.

Zusammengefasst habe ich folgendes gemacht.

Tabelle A gesichert als Tabelle A_backup
In Tabelle A die hinteren x Spalten gelöscht
In Tabelle A y neue Spalten hinten angehängt
In Tabelle A die x Spalten (leer) neu angehängt
Update von Tabelle A_Backup nach Tabelle A, um die leeren x Spalten wieder korrekt zu befüllen.

Das - nunmehr funktionierende - sql-Statement für das update lautet

update data_standard set editor = (select editor from data_standard_backup where (data_standard.pcon,data_standard.datatype) = (data_standard_backup.pcon, data_standard_backup.datatype));

Und gestern lief es mit einer anderen strukturgleichen Tabelle nicht - kein PEBKAC.

Die neuen Spalten hätte ich auch einfach hinten anhängen können. Hätte aber Probleme mit einem Excel-Frontend bereitet, das leider noch etwa 12 Monate wird verwendet werden müssen. Danach kann ich mir solche Aktionen wie “Spalten einfügen” Gott sei Dank auch schenken.

Eremit

Wenn du die Tabellen gelöscht hast, ist es zu spät, das noch herauszufinden.

pg_dump ist das Backup-Werkzeug von PostgreSQL.
Damit solltest du dich als einen deiner nächsten Schritte beschäftigen :wink:

Danke für den Tip. Dumps habe ich bisher nur über die phpPgAdmin_Oberfläche generiert.

Ich denke, damit können wir diesen Thread erstmal schließen. Vielen Dank

Eremit

pgAdmin verwendet pg_dump um dumps zu erzeugen

Richtig - nur ist das nicht automatisiert.

Und ein Backup braucht man immer dann, wenn man gerade eines ziehen wollte.