[PHP/MySQL]Datenbankeintrag kopieren und zwei Werte anpassen?

BartTheDevil89

Devilution Media
ID: 87739
L
2 Mai 2006
3.960
103
Hallo,

ich melde mich jetzt hier auch mal wieder zu Worte. :D Und habe natürlich gleich wieder ein Problem, bzw. eine Frage...;)

Denn ich habe eine Tabelle.

ID/Wert1/Wert2/Wert3...

und einen Datenbankeintrag:

2/Opa/Oma/Onkel...

Die Aufgabe besteht nun darin eine komplette Kopie des Eintrages zu erstellen und beispielsweise Wert1 und Wert3 zu ändern.

Soll also das dann rauskommen beispielsweise:

3/Kind/Oma/Bruder...

Die 3 ändert sich automatisch, da die ID auto_increment ist.

Aber gibts da irgendwie ne elegantere Lösung außer select und insert? Denn hinter den ... sind noch ne Menge mehr Einträge.

Danke
 
INSERT INTO ... SELECT ;)

Isn eigenes Statement.
 
INSERT INTO ... SELECT ;)

Isn eigenes Statement.

Das heißt du meinst es so?

PHP:
insert into tabelle (Wert1,Wert2,Wert3....) select Wert1,Wert2,Wert3... from tabelle where ID = 2

Nur halt mit Wert1 und Wert3 eben noch durch meine Wünsche ersetzt. Richtig?
Denn dann änderts für mich ja auch nichts. Ich muss ja trotzdem jede neue Spalte angeben und das wollte ich eigentlich vermeiden.

Oder lässt es sich ermöglichen mit insert into und select einfach das Ding komplett zu kopieren nur eben die id-spalte rauslassen? Denn dann kann ich mir ja neue ID holen und dafür einfach noch die beiden Werte mit ner extra Abfrage dann ändern.
 
PHP:
INSERT INTO foobar (wert1, wert2, wert3) SELECT "foo", wert2, "bar" FROM andereTabelle WHERE kriterium=1

Ja wie das läuft hab ich schon verstanden...aber oben die ... heißen ja, dass es da noch ne menge mehr spalten gibt. Das heißt ich müsste das Ding so machen:

PHP:
INSERT INTO foobar (wert1, wert2, wert3,wert4,wert5....) SELECT "foo", wert2, "bar", wert4, wert5, wert6.... FROM andereTabelle WHERE kriterium=1

Und ich müsste dann ja alle Spalten hier aufzählen und sobald eine dazukommt diese dort ja auch angeben. Und das möchte ich eben vermeiden.
 
Eine Spalte kann nicht dazukommen. Das Datenbankschema ist fest 8O
 
Ja nein ich meine falls ich mal ne spalte in Schema einfüge. Also noch ein Wert33 benötige zum Beispiel, dann will ich das dort nichtmehr mit angeben müssen.

Also in deinem PHP-Script? Dann müsstest du dir vorher alle Spalten über ein Describe-Statement ausgeben lassen

https://dev.mysql.com/doc/refman/5.0/en/describe.html

und dann das SQL-Statement dynamisch nach dem vorgeschlagenen Muster zusammenbauen. Du musst leider der DB schon sagen, welche Spalten relevant sein sollen (vor allem beim Insert ;))
 
Ja nein ich meine falls ich mal ne spalte in Schema einfüge.
Nochmal: Ein Datenbankschema ist fest! Da wird nichts mehr im Nachhinein eingefügt.

Da du deine Spalten hier im Thread immer schön mit wert(fortlaufenderNummer) ansprichst, gehe ich - :roll: - davon aus, dass hier schon wieder ein Verstoß gegen die allererste Normalform vorliegt.
 
Also ich glaube, dass es für dein Problem keine elegantere Lösung gibt, als deine angesprochene:

PHP:
    function maybe_quote($value) {
        return !is_numeric($value) ? "'" . $value . "'" : $value;

    }

    $src = mysql_fetch_assoc(mysql_query("SELECT * FROM tbl WHERE ID = x"));
    // überschreiben der zu ändernden Spalten
    $src['wert1'] = 'neuer Wert';
    // usw.

    unset($src['ID']); // nutze Auto-Increment
    
    $src = array_map('maybe_quote', $src);    

    mysql_query("INSERT INTO tbl(" . implode(',', array_keys($src)) . ") VALUES(" . implode(',', $src). ")");

Ugly, aber sollte funktionieren ;)

Edit: die maybe_quote()-Funktion könnte man natürlich etwas erweitern um beispielsweise Arrays automatisch zu serialisieren, etc.

Greetz

paddya
 
Zuletzt bearbeitet:
Also beispiel konkreter:

Ne Usertabelle mit

ID/Username/Passwort/eMail

ist bisher gesetzt. Wenn ich dort drin jetzt einen Datensatz kopieren möchte würde ich das so machen:

Code:
INSERT INTO foobar (Username,Passwort,eMail) SELECT "ichbineinneuerusername", Passwort, "neueEmail" FROM andereTabelle WHERE kriterium=1
Ich weiß, dass es jetzt keinen Sinn macht nen User zu kopieren aber vom System her.

Würde ja funktionieren. Aber was ist wenn mir jetzt nachher noch eine Spalte Adresse oder so noch einfällt. Also sich das Datenbankschema noch um die Spalte Adresse erweitert wird.
Müsste ich ja eigentlich in dem Code oben noch ,Adresse und ,Adresse mit angeben.
Aber das würde ich gern vermeiden weil die DB auch bisschen größer ist wie das Beispiel hier.
Daher eben die Idee einfach einen neuen Eintrag mit ALLEN Daten zu kopieren bis auf die erste Spalte. Geht es also auch anders herum?


[/CODE]
 
Als 2. Möglichkeit zu dem von paddya angesprochenen könntest du sowas machen:

PHP:
mysql_query('INSERT INTO foobar FROM andereTabelle');
$id = mysql_last_insert_id();
mysql_query('UPDATE SET email="foo@foo.de" WHERE id='.$id);

Allerdings müssen dann die Tabellen komplett identisch sein!
 
Es ist ja sogar die gleiche Tabelle^^....und deine Idee ist ja genau meine Idee. Aber das Problem ist, dass die erste Spalte also ID eine auto_increment - Spalte ist. Und wenn ich jetzt versuche die ID der vorhergehenden Spalte einzutragen gibts ja nen Error.
 
Es ist ja sogar die gleiche Tabelle^^....und deine Idee ist ja genau meine Idee. Aber das Problem ist, dass die erste Spalte also ID eine auto_increment - Spalte ist. Und wenn ich jetzt versuche die ID der vorhergehenden Spalte einzutragen gibts ja nen Error.

Guck mal meinen Code durch ;) Da ist ne Zeile mit dem Kommentar "nutze Auto-Increment".

Greetz

paddya
 
Mein Gedanke

Was wäre mit:
Code:
CREATE TEMPORARY TABLE tmp123 SELECT * FROM meine_daten WHERE id=[b]15[/b];
UPDATE tmp123 SET id=0, [b]wert1='Kind', wert3='Bruder';[/b]
INSERT INTO meine_daten SELECT * FROM tmp123;
DROP TEMPORARY TABLE tmp123;
- id ist der primäre Schlüssel (aus 0 wird nachher Auto gemacht)
- die 15 ist in diesem Beispiel der alte Datensatz, wert1, wert3 sind die neuen Werte
- tmp123, irgendein freier Tabellen-Namen

Ich denke, das ist zwar nicht die ultimative Lösung, aber unter Umständen vielleicht brauchbar. Vielleicht kann sich ein Informatiker mal äußern und varraten, ob mein Ansatz Tücken/Haken hat. ;)