Um in mySQL einen Datensatz (record) in einer Tabelle (table) zu kopieren und dabei gleichzeitig eine neue ID zu vergeben, nutzen Sie folgenden SQL Befehl in einem Aufruf:
CREATE TEMPORARY TABLE tmp SELECT * FROM beispiel WHERE id = 123;
UPDATE tmp SET id = null;
INSERT INTO beispiel SELECT * FROM tmp;
Die Erklärung:
Sie erstellen eine temporäre Tabelle ("tmp") aus dem Datensatz Nr. 123 der Tabelle "beispiel". Dadurch werden gleichzeitig die Felder der Tabelle ausgelesen und zwischengespeichert. Dann setzen Sie die ID in der Kopie auf "null" (das Feld wird geleert) und fügen diesen modifizierten Datensatz gleich wieder ein.
Weitere Möglichkeiten:
Natürlich können Sie im mittleren Schritt (hier das Setzen der ID auf "null") auch andere Veränderungen am Datensatz durchführen. Wenn Sie z.Bsp. das Feld "name" mit "Max Muster" füllen möchten, nutzen Sie folgenden Befehl:
CREATE TEMPORARY TABLE tmp SELECT * FROM beispiel WHERE id = 123;
UPDATE tmp SET id = null, name = 'Max Muster';
INSERT INTO beispiel SELECT * FROM tmp;
Auch das Verarbeiten / Kopieren mehrerer Datensätze in einem Aufruf ist möglich:
CREATE TEMPORARY TABLE tmp SELECT * FROM beispiel WHERE id > 123;
UPDATE tmp SET id = null;
INSERT INTO beispiel SELECT * FROM tmp;
Im Beispiel werden zuerst alle Datensätze (records) mit einer ID über 123 in die temporäre Tabelle kopiert, dann deren ID auf "null" gesetzt und anschließend alle wieder in die Tabelle eingefügt. Dabei beachten Sie bitte, dass evtl. sehr viele Datensätze erzeugt werden können. Haben Sie z.Bsp. 10.000 Einträge über der ID 123, dann haben Sie nach diesem SQL Befehl 20.000 in der Tabelle ...
Als Ergänzung und Hilfe für unsere PERL Benutzer haben wir folgendes Beispiel von einem Benutzer erhalten. Es zeigt den Aufruf per PERL:DBI und soll als Muster dienen - in der Praxis werden einige die "use strict" Definitionen einpflegen wollen.
# 1.
$sql = "CREATE TEMPORARY TABLE tmp SELECT * FROM Tabelle WHERE ID = '".$F{ID}."'";
my $query = $db->prepare($sql);
die "Error: $DBI::errstr\n" if $DBI::err;
$query->execute();
die "Error: $DBI::errstr\n" if $DBI::err;
# 2.
$sql = "UPDATE tmp SET ID = NULL";
$query = $db->prepare($sql);
die "Error: $DBI::errstr\n" if $DBI::err;
$query->execute();
die "Error: $DBI::errstr\n" if $DBI::err;
# 3.
$sql = "INSERT INTO Tabelle SELECT * FROM tmp";
$query = $db->prepare($sql);
die "Error: $DBI::errstr\n" if $DBI::err;
$query->execute();
die "Error: $DBI::errstr\n" if $DBI::err;
$meldung = "Der Eintrag wurde kopiert.";
Für das Beispiel vielen Dank an Otto von www.sitemachine.net
Ich denke es ist einfacher mit einem INSERT INTO und anschließendem SELECT.
z.B.
INSERT INTO TBL_TEST (TXTTEXT,INTZAHL)
SELECT TXTTEXT,INTZAHL
FROM TBL_TEST
WHERE ID = 1;
Damit wird der über ID =1 gefundene Datensatz einfach nochmal eingesetzt. Dabei werden Automatismen wie z.B. der Autowert automatisch in die Tabelle eingetragen. Ein ID = NULL fällt hier einfach weg. Über last_insert_id() lässt sich zur Not auch die neue ID feststellen, um Änderung am Datensatz vorzunehmen.
Danke für den Tipp.
Es fehlt allerdings noch etwas vor dem Setzen der id auf null, da diesen Wert gewöhnlich nicht annehmen darf:
ALTER TABLE tmp MODIFY id INT;
Die Variante von Herrn Bromberger hat zwei Vorteile:
1. Man verwendet nur eine Zeile, was durch eine Prozedur behoben werden könnte.
2. Man kann sich zusammensuchen, welche Spalten kopiert werden sollen.
Der zweite Punkt kann allerdings auch ein Nachteil sein, wenn sich die Struktur der Tabelle im Laufe der Zeit/Entwicklungsphase ändert. Dann müsste jede Stelle des Codes an der dieses Statement verwendet wurde u.U. korrigiert werden.