Kann ich in MySQL eine Zeile kopieren, um sie in dieselbe Tabelle einzufügen?

162
insert into table select * from table where primarykey=1

Ich möchte nur eine Zeile kopieren, um sie in dieselbe Tabelle einzufügen (dh ich möchte eine vorhandene Zeile in der Tabelle duplizieren), aber ich möchte dies tun, ohne alle Spalten nach dem "Auswählen" auflisten zu müssen, da diese Tabelle hat zu viele Spalten.

Aber wenn ich das mache, bekomme ich den Fehler:

Doppelter Eintrag 'xxx' für Schlüssel 1

Ich kann damit umgehen, indem ich eine weitere Tabelle mit denselben Spalten wie ein temporärer Container für den Datensatz erstelle, den ich kopieren möchte:

create table oldtable_temp like oldtable;
insert into oldtable_temp select * from oldtable where key=1;
update oldtable_tem set key=2;
insert into oldtable select * from oldtable where key=2;

Gibt es einen einfacheren Weg, dies zu lösen?

Lina
quelle
Ich habe nur einen Kommentar zu den fest codierten Werten für den Schlüssel. Ich würde so etwas tun, max(oldtable.id) + oldtable_temp.keyum sicherzustellen, dass die IDs inkrementieren und eindeutig sind.
Kerl Mograbi
Mögliches Duplikat von Duplikat- / Kopierdatensätzen in derselben MySQL-Tabelle
Organic Advocate
@OrganicAdvocate dies hat mehr Antworten und mehr Ansichten als diese Frage
Drew

Antworten:

189

Ich habe Leonard Challis 'Technik mit ein paar Änderungen verwendet:

CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE primarykey = 1;
UPDATE tmptable_1 SET primarykey = NULL;
INSERT INTO table SELECT * FROM tmptable_1;
DROP TEMPORARY TABLE IF EXISTS tmptable_1;

Als temporäre Tabelle sollte es nie mehr als einen Datensatz geben, damit Sie sich nicht um den Primärschlüssel kümmern müssen. Wenn Sie den Wert auf null setzen, kann MySQL den Wert selbst auswählen, sodass kein Risiko besteht, ein Duplikat zu erstellen.

Wenn Sie sicher sein möchten, dass nur eine Zeile eingefügt werden kann, können Sie LIMIT 1 am Ende der Zeile INSERT INTO hinzufügen.

Beachten Sie, dass ich auch den Primärschlüsselwert (in diesem Fall 1) an meinen temporären Tabellennamen angehängt habe.

Grimmig...
quelle
3
Diese Lösung ist insofern korrekt (im Gegensatz zu einigen anderen, die Stimmen erhalten haben), als sie es MySQL ermöglicht, den Primärschlüsselwert auszuwählen.
Jan Hettich
1
Obwohl nicht genau so funktioniert, wie es aufgrund inkonsistenter temporärer Tabellennamen ( tmptable_1vs. tmptable) ist
Kieran Tully
9
Wie kann ein Primärschlüssel null sein?
Imran Shafqat
5
Wenn es null ist, wird ihm beim Einfügen automatisch die nächste KI-Nummer zugewiesen.
Grimmig ...
2
IMRAN - Sie können gut fragen. Ich dachte, dass das ID-Feld der temporären Tabelle möglicherweise nicht automatisch zu einer PK gemacht wurde (ich bin mir ziemlich sicher, dass SQL Server dies unter diesen Umständen nicht tut), aber es ist so. Ich musste ALTER TABLE tmptable_1 MODIFY primarykeyINT NULL ausführen ; nach der ersten Zeile, damit die Lösung funktioniert
DJDave
60

Update 07/07/2014 - Die Antwort, die auf meiner Antwort von Grim ... basiert , ist eine bessere Lösung, da sie meine unten stehende Lösung verbessert. Daher würde ich vorschlagen, diese zu verwenden.

Sie können dies tun, ohne alle Spalten mit der folgenden Syntax aufzulisten:

CREATE TEMPORARY TABLE tmptable SELECT * FROM table WHERE primarykey = 1;
UPDATE tmptable SET primarykey = 2 WHERE primarykey = 1;
INSERT INTO table SELECT * FROM tmptable WHERE primarykey = 2;

Sie können den Primärschlüssel auch auf andere Weise ändern.

LeonardChallis
quelle
16
Dies ist im Grunde die gleiche Lösung, die das OP bereits für sein eigenes Problem bereitgestellt hatte, allerdings mit tatsächlichen temporären Tabellen und einem etwas saubereren Erstellungsmuster. Ich denke, das OP hat nach einem besseren Ansatz für das gefragt , was sie bereits verwendet haben, und nicht nach einer Bereinigung ihrer vorhandenen Syntax. Verstehe nicht wirklich alle positiven Stimmen dafür.
September
Danke dir. Es läuft gut mit dynamischer Funktion
Sonal Khunt
Muss die tmptable nach Abschluss dieses Vorgangs gelöscht werden?
SSH Diesen
"Standardmäßig werden alle temporären Tabellen von MySQL gelöscht, wenn Ihre Datenbankverbindung beendet wird. Sie möchten sie jedoch zwischendurch löschen, indem Sie den Befehl DROP TABLE ausgeben." Mehr hier
LeonardChallis
Wenn Sie das erstellt haben tmptable, müssen Sie die WHERE primarykey = 2Anweisung auch nicht für die letzte Zeile hinzufügen . (Dh nur INSERT INTO table SELECT * FROM tmptable.)
Marcus
42

Ich gehe davon aus, dass Sie möchten, dass der neue Rekord einen neuen hat primarykey? Wenn primarykeyist AUTO_INCREMENTdann dies nur tun:

INSERT INTO table (col1, col2, col3, ...)
SELECT col1, col2, col3, ... FROM table
  WHERE primarykey = 1

... wo col1, col2, col3, ...sind alle Spalten in der Tabelle außer primarykey .

Wenn es sich nicht um eine AUTO_INCREMENTSpalte handelt und Sie den neuen Wert auswählen möchten, ist primarykeyer ähnlich:

INSERT INTO table (primarykey, col2, col3, ...)
SELECT 567, col2, col3, ... FROM table
  WHERE primarykey = 1

... wo 567ist der neue Wert für primarykey.

Jordan läuft
quelle
41
Wie kommt es, dass dies sieben Mal positiv bewertet wird, wenn die Frage ignoriert wird? ... aber ich möchte nicht alle Spalten nach dem "Auswählen"
auflisten
7
-1, da dies genau das ist, was das OP vermeiden möchte. Lesen Sie die Frage oder geben Sie zumindest eine Antwort wie "Dies ist der einzig mögliche Weg".
Devios1
5
Denn manchmal ist die Frage selbst falsch. :) Das Duplizieren von Zeilen ohne Änderung des Inhalts erhöht die Redundanz. Wenn möglich, sollte empfohlen werden, die Datenbankstruktur zu ändern, um die Redundanz zu minimieren.
Torben
4
Nur weil es unter normalen Praktiken nicht richtig ist, macht es nichts falsch. Es gibt viele Fälle, in denen Standard-Best Practices nicht angewendet werden. Beispiel: Die Datenbank stellt Dokumente dar und ein Benutzer muss eine Kopie eines Dokuments aufbewahren, bevor er Änderungen vornimmt.
ima747
6
Weil Sie möglicherweise auf dieser Seite landen und nicht genau das gleiche wollen wie das OP
jx12345
13

Bei Ihrer ersten Abfrage hatten Sie es fast geschafft, nur die Spalten anzugeben. Auf diese Weise können Sie Ihren Primärschlüssel in der Einfügung ausschließen, wodurch das automatische Inkrement ausgeführt wird, das Sie wahrscheinlich in der Tabelle haben, um automatisch einen neuen Primärschlüssel für das zu erstellen Eintrag.

Ändern Sie dies beispielsweise:

insert into table select * from table where primarykey=1

Dazu:

INSERT INTO table (col1, col2, col3) 
SELECT col1, col2, col3 
FROM table 
WHERE primarykey = 1

Fügen Sie die Primärschlüsselspalte weder in die Spaltenliste für die INSERT- noch für die SELECT-Teile der Abfrage ein.

Braeden Schwarz
quelle
1
Gibt es eine Möglichkeit, die meisten Spalten durch die select-Anweisung zu ziehen, aber eine davon manuell im Befehl insert zu aktualisieren? wie insert into table ("val1", col2, col3) select col2, col3 from table where primarykey = 1oder ähnliches?
anon58192932
1
Fand es! Kopieren Sie Werte aus einer Zeile, aber fügen Sie einen Ihrer eigenen Werte in die Einfügeanweisung ein
anon58192932
1
Entschuldigung, wurde gerade über Ihre Fragen informiert, ich bin froh, dass Sie sie gefunden haben, das ist in der Tat der Weg.
Braeden Black
9

Sie können auch versuchen, die Tabelle zu sichern, den Einfügebefehl zu finden und zu bearbeiten:

mysqldump -umyuser -p mydatabase --skip-extended-insert mytable > outfile.sql

Das --skip-extended-insertgibt Ihnen einen Einfügebefehl pro Zeile. Sie können dann die Zeile in Ihrem bevorzugten Texteditor finden, den Befehl extrahieren und den Primärschlüssel auf "Standard" ändern.

nicht erfolgreich
quelle
2
+1 von mir, da dies ein guter "außerhalb der Box" -Ansatz ist, der unter bestimmten Umständen außerhalb der Laufzeit hilfreich sein kann. In erster Linie ist es jedoch die erste Antwort, die sich tatsächlich mit der Frage des OP befasst und nicht nur die vom OP bereits bereitgestellte Lösung syntaktisch optimiert.
September
6

Bei diesem Verfahren wird Folgendes vorausgesetzt:

  • Sie haben keine _duplicate_temp_table
  • Ihr Primärschlüssel ist int
  • Sie haben Zugriff auf die Erstellung einer Tabelle

Natürlich ist dies nicht perfekt, aber in bestimmten (wahrscheinlich den meisten) Fällen wird es funktionieren.

DELIMITER $$
CREATE PROCEDURE DUPLICATE_ROW(copytable VARCHAR(255), primarykey VARCHAR(255), copyid INT, out newid INT)
BEGIN
        DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @error=1;
        SET @temptable = '_duplicate_temp_table';
        SET @sql_text = CONCAT('CREATE TABLE ', @temptable, ' LIKE ', copytable);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('INSERT INTO ', @temptable, ' SELECT * FROM ', copytable, ' where ', primarykey,'=', copyid);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('SELECT max(', primarykey, ')+1 FROM ', copytable, ' INTO @newid');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('UPDATE ', @temptable, ' SET ', primarykey, '=@newid');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('INSERT INTO ', copytable, ' SELECT * FROM ', @temptable, '');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('DROP TABLE ', @temptable);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SELECT @newid INTO newid;
END $$
DELIMITER ;

CALL DUPLICATE_ROW('table', 'primarykey', 1, @duplicate_id);
SELECT @duplicate_id;
Piotr Kaczmarek
quelle
1
+1 Ich habe dies nicht bestätigt, worksaber der Ansatz ist solide und von Wert, da er hier einzigartig ist und tatsächlich die Frage des OP beantwortet.
September
5

Wenn das Primärschlüsselfeld Ihrer Tabelle ein automatisches Inkrementfeld ist, können Sie die Abfrage mit Spalten verwenden. Zum Beispiel hat Ihre Tabelle mit dem Namen test_tbl3 Felder als id, name, age. idist ein Primärschlüsselfeld und ein automatisches Inkrementieren, sodass Sie die folgende Abfrage verwenden können, um die Zeile zu duplizieren:

INSERT INTO `test_tbl` (`name`,`age`) SELECT `name`,`age` FROM `test_tbl`;

Diese Abfrage führt dazu, dass jede Zeile dupliziert wird.


Wenn das Primärschlüsselfeld Ihrer Tabelle kein automatisches Inkrementfeld ist, können Sie die folgende Methode verwenden:

INSERT INTO `test_tbl` (`id`,`name`,`age`)
  SELECT 20,`name`,`age` FROM `test_tbl` WHERE id = 19;

Das Ergebnis dieser Abfrage ist eine doppelte Zeile von id=19eingefügt als id=20.

user2595171
quelle
Das ist die beste Antwort ist, der Fall ist ziemlich einfach: INSERT INTO tableName( fieldName1, fieldName2, fieldName3) SELECT fieldName1, fieldName2, fieldName3VON tableNameDENEN 1 (alle von ihnen auf einmal kopieren)
jakubplus
Abgeordnet - diese Antwort ist prägnant und im Sinne des tatsächlichen "Kopierens" einer Zeile.
user37309
4

Dies kann mit etwas Kreativität erreicht werden:

SET @sql = CONCAT('INSERT INTO <table> SELECT null, 
    ', (SELECT GROUP_CONCAT(COLUMN_NAME) 
    FROM information_schema.columns 
    WHERE table_schema = '<database>' 
    AND table_name = '<table>' 
    AND column_name NOT IN ('id')), ' 
from <table> WHERE id = <id>');  

PREPARE stmt1 FROM @sql;
EXECUTE stmt1;

Dies führt dazu, dass die neue Zeile anstelle der ID aus der ausgewählten Zeile eine automatisch inkrementierte ID erhält.

curmil
quelle
4

Klonzeile mit Aktualisierungsfeldern und automatischem Inkrementierungswert

CREATE TEMPORARY TABLE `temp` SELECT * FROM `testing` WHERE id = 14;

UPDATE `temp` SET id = (SELECT id FROM testing ORDER by id DESC LIMIT 1
 )+1, user_id = 252 ,policy_no = "mysdddd12" where id = 14;

INSERT INTO `testing` SELECT * FROM `temp`;

DROP TEMPORARY TABLE IF EXISTS `temp`;
Shrinivas Mahindrakar
quelle
@Torben Bitte überprüfen Sie das Häkchen links neben der Frage (markieren Sie es als akzeptiert), damit jeder weiß, dass es für Sie funktioniert hat.
HosseyNJF
3

Einige der folgenden Informationen wurden von dieser Website abgerufen. Folgendes habe ich getan, um einen Datensatz in einer Tabelle mit einer beliebigen Anzahl von Feldern zu duplizieren:

Dies setzt auch voraus, dass Sie am Anfang der Tabelle ein KI-Feld haben

function duplicateRow( $id = 1 ){
dbLink();//my db connection
$qColumnNames = mysql_query("SHOW COLUMNS FROM table") or die("mysql error");
$numColumns = mysql_num_rows($qColumnNames);

for ($x = 0;$x < $numColumns;$x++){
$colname[] = mysql_fetch_row($qColumnNames);
}

$sql = "SELECT * FROM table WHERE tableId = '$id'";
$row = mysql_fetch_row(mysql_query($sql));
$sql = "INSERT INTO table SET ";
for($i=1;$i<count($colname)-4;$i++){//i set to 1 to preclude the id field
//we set count($colname)-4 to avoid the last 4 fields (good for our implementation)
$sql .= "`".$colname[$i][0]."`  =  '".$row[$i]. "', ";
}
$sql .= " CreateTime = NOW()";// we need the new record to have a new timestamp
mysql_query($sql);
$sql = "SELECT MAX(tableId) FROM table";
$res = mysql_query($sql);
$row = mysql_fetch_row($res);
return $row[0];//gives the new ID from auto incrementing
}
richardwhitney
quelle
2

Ich bin vielleicht zu spät dran, aber ich habe eine ähnliche Lösung, die für mich funktioniert hat.

 INSERT INTO `orders` SELECT MAX(`order_id`)+1,`container_id`, `order_date`, `receive_date`, `timestamp` FROM `orders` WHERE `order_id` = 1

Auf diese Weise muss ich keine temporäre Tabelle usw. erstellen. Da die Zeile in dieselbe Tabelle kopiert wird, Max(PK)+1kann die Funktion problemlos verwendet werden.

Ich suchte nach einer Lösung für diese Frage (hatte die Syntax vergessen) und stellte schließlich meine eigene Frage. Komisch, wie es manchmal läuft.

Grüße

echo_salik
quelle
2

Wenn der Primärschlüssel Auto Increment ist, geben Sie einfach jedes Feld außer dem Primärschlüssel an.

INSERT INTO table(field1,field2,field3) SELECT (field1,field2,field3) FROM table WHERE primarykey=1

Fedy Venom
quelle
2

Ich habe die Lösung von @ LeonardChallis aktualisiert, da sie für mich wie keine der anderen nicht funktioniert hat. Ich habe die WHEREKlauseln und SET primaryKey = 0die temporäre Tabelle entfernt, damit MySQL den primären Schlüssel automatisch inkrementiert

CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable;
UPDATE tmptable SET primaryKey = 0;
INSERT INTO myTable SELECT * FROM tmptable;

Dies dient natürlich dazu, alle Zeilen in der Tabelle zu duplizieren .

D4V1D
quelle
2

Ich habe Grims Technik mit einer kleinen Änderung verwendet: Wenn jemand nach dieser Abfrage sucht, weil er aufgrund eines Primärschlüsselproblems keine einfache Abfrage durchführen kann:

INSERT INTO table SELECT * FROM table WHERE primakey=1;

Bei meiner MySql-Installation 5.6.26 ist der Schlüssel nicht nullwertfähig und führt zu einem Fehler:

#1048 - Column 'primakey' cannot be null 

Nachdem ich eine temporäre Tabelle erstellt habe, ändere ich den Primärschlüssel in null.

CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE primarykey = 1;
ALTER TABLE tmptable_1 MODIFY primarykey int(12) null;
UPDATE tmptable_1 SET primarykey = NULL;
INSERT INTO table SELECT * FROM tmptable_1;
DROP TEMPORARY TABLE IF EXISTS tmptable_1;
Luca Camillo
quelle
Alternativ kann in neuen Versionen von mariadb / mysql der primäre Schlüssel auf 0 gesetzt werden, damit das automatische Inkrement beim Einfügen funktioniert.
Shelbypereira
2

Ich würde unten verwenden,

insert into ORDER_ITEM select * from ORDER_ITEM where ITEM_NUMBER =123;
Ishan Liyanage
quelle
1
Dies funktioniert nicht, wenn ITEM_NUMBER Ihr Primärschlüssel ist, was in dieser Situation wahrscheinlich ist.
Billy Pilgrim
2

Ich habe in meiner Koha-Datenbank doppelte Elemente mit dem Präfix 'C' in die Barcode- Spalte eingefügt :

INSERT INTO items (`biblionumber`, `biblioitemnumber`, `barcode`, `dateaccessioned` ) SELECT `biblionumber`, `biblioitemnumber`,  CONCAT('C',`barcode`), `dateaccessioned` FROM `items` WHERE barcode='14832';
Rajiv Mahmud
quelle
1

Ich musste das nur tun und das war meine manuelle Lösung:

  1. Überprüfen Sie in phpmyadmin die Zeile, die Sie kopieren möchten
  2. Klicken Sie unten unter Abfrageergebnisoperationen auf "Exportieren".
  3. Aktivieren Sie auf der nächsten Seite "Als Datei speichern" und klicken Sie auf "Los".
  4. Öffnen Sie die exportierte Datei mit einem Texteditor, suchen Sie den Wert des primären Felds und ändern Sie ihn in etwas Einzigartiges.
  5. Zurück in phpmyadmin klicken Sie auf die Registerkarte 'Importieren' , suchen Sie die zu importierende SQL-Datei unter Durchsuchen , klicken Sie auf 'Los' und die doppelte Zeile sollte eingefügt werden.

Wenn Sie nicht wissen, was das PRIMARY- Feld ist, schauen Sie auf Ihre phpmyadmin- Seite zurück, klicken Sie auf die Registerkarte 'Struktur' und unten auf der Seite unter 'Indizes' wird angezeigt, welches 'Feld' einen 'Schlüsselnamen' hat. Wert 'PRIMARY' .

Ein bisschen weit weg, aber wenn Sie sich nicht mit Markups befassen möchten und nur eine einzelne Zeile duplizieren müssen, können Sie loslegen.

user27068
quelle
Schön, antwortet die Operation auf eine Art Out-of-the-Box-Art. Funktioniert natürlich nicht in allen Fällen, z. B. bei Blobs und Geodaten, ist aber ziemlich einfach abzurufen und funktioniert bei diesen seltsamen Ballwechseln.
Strixy
1

Diese oben gezeigte Lösung funktioniert auch für ausgewählte Zeilen perfekt. Zum Beispiel erstelle ich Demonstrationszeilen für mein nice2work-Projekt, und das funktioniert perfekt.

CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable WHERE id=500;
UPDATE tmptable SET id = 0;
UPDATE some fields I need to change
INSERT INTO myTable SELECT * FROM tmptable;
DROP TABLE tmptable;

//  You can use this same also directly into your code like (PHP Style)
$sql = "CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable WHERE id=500;
UPDATE tmptable SET id = 0;
UPDATE some fields I need to change
INSERT INTO myTable SELECT * FROM tmptable;DROP TABLE tmptable;";
Ronald Stevens
quelle
0

Entschuldigung für den Nekropost, aber das ist es, was ich bei Google gefunden habe. Da ich dies hilfreich, aber problematisch fand, wollte ich eine wichtige Modifikation für alle anderen beitragen, die dies ausgraben.

Zunächst einmal verwende ich SQL Server, nicht MySQL, aber ich denke, es sollte ähnlich funktionieren. Ich habe die Lösung von Leonard Challis verwendet, weil sie am einfachsten war und die Anforderungen erfüllte. Es gibt jedoch ein Problem: Wenn Sie einfach die PK nehmen und um 1 erhöhen, was passiert, wenn Sie andere Datensätze hinzugefügt haben, seit die betreffende Zeile hinzugefügt wurde . Ich entschied, dass es am besten ist, das System die automatische Inkrementierung der PK durchführen zu lassen, also habe ich Folgendes getan:

SELECT * INTO #tmpTable FROM Table WHERE primarykey = 1
--Optionally you can modify one or more fields here like this: 
--UPDATE #tmpTable SET somefield = newData
ALTER TABLE #tmpTable DROP COLUMN TicketUpdateID
INSERT INTO Tickets SELECT * FROM #tmpTable
DROP TABLE #tmpTable

Ich glaube, dass dies in MySQL ähnlich funktionieren würde, aber ich kann das leider nicht testen

maxx233
quelle
1
total bakwaas Antwort
AsadYarKhan
0

Ich weiß, dass es eine alte Frage ist, aber hier ist eine andere Lösung:

Dadurch wird eine Zeile in der Haupttabelle dupliziert, vorausgesetzt, der Primärschlüssel wird automatisch erhöht, und es werden Kopien der Daten verknüpfter Tabellen mit der neuen ID der Haupttabelle erstellt.

Weitere Optionen zum
Abrufen von Spaltennamen : -SHOW COLUMNS FROM tablename; (
Spaltenname : Feld) -DESCRIBE tablename ( Spaltenname : Feld)
-SELECT Spaltenname FROM information_schema.columns WHERE Tabellenname = 'Tabellenname' (Spaltenname: Spaltenname)

//First, copy main_table row
$ColumnHdr='';
$Query="SHOW COLUMNS FROM `main_table`;";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
while($Row=mysql_fetch_array($Result))
{
    if($Row['Field']=='MainTableID')     //skip main table id in column list
        continue;
    $ColumnHdr.=",`" . $Row['Field'] . "`";
}
$Query="INSERT INTO `main_table` (" . substr($ColumnHdr,1) . ")
        (SELECT " . substr($ColumnHdr,1) . " FROM `main_table`
            WHERE `MainTableID`=" . $OldMainTableID . ");";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
$NewMainTableID=mysql_insert_id($link);

//Change the name (assumes a 30 char field)
$Query="UPDATE `main_table` SET `Title`=CONCAT(SUBSTRING(`Title`,1,25),' Copy') WHERE `MainTableID`=" . $NewMainTableID . ";";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);

//now copy in the linked tables
$TableArr=array("main_table_link1","main_table_link2","main_table_link3");
foreach($TableArr as $TableArrK=>$TableArrV)
{
    $ColumnHdr='';
    $Query="SHOW COLUMNS FROM `" . $TableArrV . "`;";
    $Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
    while($Row=mysql_fetch_array($Result))
    {
        if($Row['Field']=='MainTableID')     //skip main table id in column list, re-added in query
            continue;
        if($Row['Field']=='dbID')    //skip auto-increment,primary key in linked table
            continue;
        $ColumnHdr.=",`" . $Row['Field'] . "`";
    }

    $Query="INSERT INTO `" . $TableArrV . "` (`MainTableID`," . substr($ColumnHdr,1) . ")
            (SELECT " . $NewMainTableID . "," . substr($ColumnHdr,1) . " FROM `" . $TableArrV . "`
             WHERE `MainTableID`=" . $OldMainTableID . ");";
    $Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
}
Paul
quelle
0

max233 war sicherlich auf dem richtigen Weg, zumindest für den Autoincrement-Fall. Führen Sie jedoch nicht die ALTER TABLE aus. Setzen Sie einfach das Feld für die automatische Inkrementierung in der temporären Tabelle auf NULL. Dies stellt einen Fehler dar, aber das folgende EINFÜGEN aller Felder in der temporären Tabelle wird ausgeführt und das NULL-Auto-Feld erhält einen eindeutigen Wert.

user3067083
quelle
0

Erstellen Sie eine Tabelle

    CREATE TABLE `sample_table` (
       `sample_id` INT(10) unsigned NOT NULL AUTO_INCREMENT,
       `sample_name` VARCHAR(255) NOT NULL,
       `sample_col_1` TINYINT(1) NOT NULL,
       `sample_col_2` TINYINT(2) NOT NULL,

      PRIMARY KEY (`sample_id`),
      UNIQUE KEY `sample_id` (`sample_id`)

    ) ENGINE='InnoDB' DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

Fügen Sie eine Zeile ein

INSERT INTO `sample_table`
   VALUES(NULL, 'sample name', 1, 2);

Klonreiheneinfügung oben

INSERT INTO `sample_table`
   SELECT 
    NULL AS `sample_id`, -- new AUTO_INCREMENT PRIMARY KEY from MySQL
    'new dummy entry' AS `sample_name`,  -- new UNIQUE KEY from you
    `sample_col_1`, -- col from old row
    `sample_col_2` -- col from old row
   FROM `sample_table`
   WHERE `sample_id` = 1;

Prüfung

SELECT * FROM `sample_table`;
Abdullah Aydın
quelle
Hinweis: Wenn Sie eine Fehlermeldung erhalten (# 1048), verwenden Sie '' anstelle von NULL
Abdullah Aydın
Ist es nur ich oder ist es genau das , was das OP nicht wollte? (Dh manuell jede Spalte zur Abfrage hinzufügen.)
Byson
Sie haben Recht, ich habe gerade den Satz "Ich möchte nur eine Zeile kopieren, um ihn in dieselbe Tabelle einzufügen" von OP gelesen. Vielleicht ist dies trotzdem nützlich für "Eintrag 'xxx' für Schlüssel duplizieren ???" Fehler ^^
Abdullah Aydın
0

Hier ist eine Antwort, die ich online auf dieser Website gefunden habe. Beschreibt, wie die oben genannten Schritte ausgeführt werden. 1 Die Antwort finden Sie unten auf der Seite. Grundsätzlich kopieren Sie die zu kopierende Zeile in eine temporäre Tabelle im Speicher. Anschließend ändern Sie die Primärschlüsselnummer mithilfe der Aktualisierung. Anschließend fügen Sie es erneut in die Zieltabelle ein. Sie lassen dann den Tisch fallen.

Dies ist der Code dafür:

CREATE TEMPORARY TABLE rescueteamENGINE = MEMORY SELECT * FROM fitnessreport4WHERE rID = 1; # 1 betroffene Zeile. UPDATE rescueteamSET rID = Null WHERE rID = 1; # 1 betroffene Zeile. INSERT INTO fitnessreport4SELECT * FROM rescueteam; # 1 betroffene Zeile. DROP TABLE rescueteam# MySQL hat eine leere Ergebnismenge zurückgegeben (dh null
Zeilen).

Ich habe das temporäre Tabellenrettungsteam erstellt. Ich habe die Zeile aus meinem ursprünglichen Tabellen-Fitnessbericht4 kopiert. Ich habe dann den Primärschlüssel für die Zeile in der temporären Tabelle auf null gesetzt, damit ich ihn zurück in die ursprüngliche Tabelle kopieren kann, ohne einen Fehler beim doppelten Schlüssel zu erhalten. Ich habe diesen Code gestern Abend ausprobiert und es hat funktioniert.

user2363682
quelle
0

Dies ist eine zusätzliche Lösung für die Antwort von "Grim ...". Es gab einige Kommentare dazu mit einem Primärschlüssel als null. Einige Kommentare dazu funktionieren nicht. Und einige Kommentare zu Lösungen. Keine der Lösungen hat bei uns funktioniert. Wir haben MariaDB mit der InnoDB-Tabelle.

Wir konnten den Primärschlüssel nicht so einstellen, dass er null zulässt. Die Verwendung von 0 anstelle von NULL führte zu einem doppelten Wertefehler für den Primärschlüssel. SET SQL_SAFE_UPDATES = 0;Hat auch nicht funktioniert.

Die Lösung von "Grim ..." hat funktioniert, wenn wir stattdessen unseren PRIMARY KEY auf UNIQUE geändert haben

Simon
quelle
-1

Ich wollte nur meinen PHP-Code veröffentlichen, weil ich denke, dass die Art und Weise, wie ich die Spalten sammle, im Code etwas sauberer ist als in den vorherigen Beispielen. Dies zeigt auch, wie Sie ein Feld leicht ändern können, in diesem Fall indem Sie eine Zeichenfolge hinzufügen. Sie können aber auch ein Fremdschlüsselfeld durch den neu hinzugefügten Datensatz ersetzen, falls Sie auch einige untergeordnete Datensätze kopieren möchten.

  // Read columns, unset the PK (always the first field in my case)
  $stmt = $conn->prepare('SHOW COLUMNS FROM template');
  $stmt->execute();

  $columns = $stmt->fetchAll();
  $columns = array_map(function ($element) { return $element['Field']; }, $columns);

  unset($columns[0]);

  // Insert record in the database. Add string COPY to the name field.
  $sql = "INSERT INTO `template` (".implode(",", $columns).")";
  if ($key = array_search('name', $columns))
      $columns[$key] = "CONCAT(name, ' COPY')";
  $sql .= " SELECT ".implode(",", $columns)." FROM `template` WHERE `id` = ".$id;

  $stmt = $conn->prepare($sql);
  $stmt->execute();
Rolandow
quelle
-2

Für eine sehr einfache Lösung können Sie die Zeile mit PHPMyAdmin als CSV-Datei exportieren und dann einfach die geänderte CSV-Datei importieren. Bearbeiten der ID / Primärschlüssel-Spalte, um vor dem Importieren keinen Wert anzuzeigen.

SELECT * FROM table where primarykey=1

Dann am Ende der Seite:

Geben Sie hier die Bildbeschreibung ein

Wo "Exportieren" steht, einfach exportieren, dann die CSV-Datei bearbeiten, um den Primärschlüsselwert zu entfernen, damit er leer ist, und dann einfach in die Datenbank importieren. Beim Import wird ein neuer Primärschlüssel zugewiesen.

Gewähren
quelle