Antworten:
Verwendung INSERT ... SELECT
:
insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1
Wo c1, c2, ...
sind alle Spalten außer id
. Wenn Sie explizit mit einer id
von 2 einfügen möchten, fügen Sie diese in Ihre INSERT-Spaltenliste und Ihre SELECT:
insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1
id
Im zweiten Fall müssen Sie sich natürlich um ein mögliches Duplikat von 2 kümmern .
IMO, das Beste scheint SQL-Anweisungen nur zum Kopieren dieser Zeile zu verwenden, während gleichzeitig nur auf die Spalten verwiesen wird, die Sie ändern müssen und möchten.
CREATE TEMPORARY TABLE temp_table ENGINE=MEMORY
SELECT * FROM your_table WHERE id=1;
UPDATE temp_table SET id=NULL; /* Update other values at will. */
INSERT INTO your_table SELECT * FROM temp_table;
DROP TABLE temp_table;
Siehe auch av8n.com - So klonen Sie einen SQL-Datensatz
Leistungen:
your_table
in eine atomare Operation eingefügt .Error Code: 1113. A table must have at least 1 column
.
SET id=NULL
kann einen Fehler verursachen Column 'id' cannot be null
. Sollte ersetzt werden durchUPDATE temp_table SET id = (SELECT MAX(id) + 1 as id FROM your_table);
Angenommen, der Tisch ist user(id, user_name, user_email)
.
Sie können diese Abfrage verwenden:
INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)
Result: near "SELECT": syntax error
Dies hat geholfen und unterstützt BLOB / TEXT-Spalten.
CREATE TEMPORARY TABLE temp_table
AS
SELECT * FROM source_table WHERE id=2;
UPDATE temp_table SET id=NULL WHERE id=2;
INSERT INTO source_table SELECT * FROM temp_table;
DROP TEMPORARY TABLE temp_table;
USE source_table;
Für eine schnelle und saubere Lösung, bei der Sie keine Spalten benennen müssen, können Sie eine vorbereitete Anweisung verwenden, wie hier beschrieben: https://stackoverflow.com/a/23964285/292677
Wenn Sie eine komplexe Lösung benötigen, damit Sie dies häufig tun können, können Sie dieses Verfahren anwenden:
DELIMITER $$
CREATE PROCEDURE `duplicateRows`(_schemaName text, _tableName text, _whereClause text, _omitColumns text)
SQL SECURITY INVOKER
BEGIN
SELECT IF(TRIM(_omitColumns) <> '', CONCAT('id', ',', TRIM(_omitColumns)), 'id') INTO @omitColumns;
SELECT GROUP_CONCAT(COLUMN_NAME) FROM information_schema.columns
WHERE table_schema = _schemaName AND table_name = _tableName AND FIND_IN_SET(COLUMN_NAME,@omitColumns) = 0 ORDER BY ORDINAL_POSITION INTO @columns;
SET @sql = CONCAT('INSERT INTO ', _tableName, '(', @columns, ')',
'SELECT ', @columns,
' FROM ', _schemaName, '.', _tableName, ' ', _whereClause);
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
END
Sie können es ausführen mit:
CALL duplicateRows('database', 'table', 'WHERE condition = optional', 'omit_columns_optional');
Beispiele
duplicateRows('acl', 'users', 'WHERE id = 200'); -- will duplicate the row for the user with id 200
duplicateRows('acl', 'users', 'WHERE id = 200', 'created_ts'); -- same as above but will not copy the created_ts column value
duplicateRows('acl', 'users', 'WHERE id = 200', 'created_ts,updated_ts'); -- same as above but also omits the updated_ts column
duplicateRows('acl', 'users'); -- will duplicate all records in the table
HAFTUNGSAUSSCHLUSS: Diese Lösung ist nur für Personen gedacht, die häufig wiederholt Zeilen in vielen Tabellen duplizieren. Es könnte in den Händen eines betrügerischen Benutzers gefährlich sein.
Sie können auch '0' als Wert für die automatisch zu erhöhende Spalte übergeben. Der richtige Wert wird beim Erstellen des Datensatzes verwendet. Dies ist so viel einfacher als temporäre Tabellen.
Quelle: Kopieren von Zeilen in MySQL (siehe den zweiten Kommentar von TRiG zur ersten Lösung von Lore)
Viele tolle Antworten hier. Unten finden Sie ein Beispiel für die gespeicherte Prozedur, die ich geschrieben habe, um diese Aufgabe für eine von mir entwickelte Web-App auszuführen:
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
-- Create Temporary Table
SELECT * INTO #tempTable FROM <YourTable> WHERE Id = Id
--To trigger the auto increment
UPDATE #tempTable SET Id = NULL
--Update new data row in #tempTable here!
--Insert duplicate row with modified data back into your table
INSERT INTO <YourTable> SELECT * FROM #tempTable
-- Drop Temporary Table
DROP TABLE #tempTable
insert into MyTable(field1, field2, id_backup)
select field1, field2, uniqueId from MyTable where uniqueId = @Id;
Wenn Sie MySQL Workbench verwenden können, können Sie dies tun, indem Sie mit der rechten Maustaste auf die Zeile klicken und "Zeile kopieren" auswählen, dann mit der rechten Maustaste auf die leere Zeile klicken und "Zeile einfügen" auswählen und dann die ID ändern Klicken Sie auf "Übernehmen".
Kopieren Sie die Zeile:
Fügen Sie die kopierte Zeile in die leere Zeile ein:
Ändern Sie die ID:
Anwenden:
Ich habe nach der gleichen Funktion gesucht, aber ich benutze MySQL nicht. Ich wollte ALLE Felder kopieren, außer natürlich den Primärschlüssel (ID). Dies war eine One-Shot-Abfrage, die in keinem Skript oder Code verwendet werden sollte.
Ich habe mich mit PL / SQL zurechtgefunden, bin mir aber sicher, dass jede andere SQL-IDE dies tun würde. Ich habe ein Basic gemacht
SELECT *
FROM mytable
WHERE id=42;
Exportieren Sie es dann in eine SQL-Datei, in der ich die finden konnte
INSERT INTO table (col1, col2, col3, ... , col42)
VALUES (1, 2, 3, ..., 42);
Ich habe es gerade bearbeitet und verwendet:
INSERT INTO table (col1, col2, col3, ... , col42)
VALUES (mysequence.nextval, 2, 3, ..., 42);
Ich neige dazu, eine Variation dessen zu verwenden, was mu zu kurz gepostet hat:
INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;
Solange die Tabellen identische Felder haben (mit Ausnahme des automatischen Inkrements in der Protokolltabelle), funktioniert dies einwandfrei.
Da ich nach Möglichkeit gespeicherte Prozeduren verwende (um anderen Programmierern, die mit Datenbanken nicht allzu vertraut sind, das Leben zu erleichtern), wird das Problem gelöst, dass Prozeduren jedes Mal aktualisiert werden müssen, wenn Sie einer Tabelle ein neues Feld hinzufügen.
Außerdem wird sichergestellt, dass beim Hinzufügen neuer Felder zu einer Tabelle diese sofort in der Protokolltabelle angezeigt werden, ohne dass Ihre Datenbankabfragen aktualisiert werden müssen (es sei denn, Sie haben natürlich Felder, die ein Feld explizit festlegen).
Warnung: Sie sollten sicherstellen, dass Sie beiden Tabellen gleichzeitig neue Felder hinzufügen, damit die Feldreihenfolge gleich bleibt. Andernfalls treten merkwürdige Fehler auf. Wenn Sie der einzige sind, der Datenbankschnittstellen schreibt UND Sie sehr vorsichtig sind, funktioniert dies gut. Andernfalls bleiben Sie bei der Benennung aller Ihrer Felder.
Hinweis: Wenn Sie nicht an einem Solo-Projekt arbeiten, werden Sie sicher nicht andere daran arbeiten, alle Feldnamen explizit aufzulisten und Ihre Protokollanweisungen zu aktualisieren, wenn sich Ihr Schema ändert. Diese Verknüpfung ist wahrscheinlich nicht die langfristigen Kopfschmerzen wert, die sie verursachen kann ... insbesondere auf einem Produktionssystem.
INSERT IN `dbMyDataBase`.`tblMyTable` (( `IdAutoincrement`, `Column2`, `Column3`, `Column4` ) WÄHLEN NULL, `Column2`, `Column3`, 'CustomValue' AS Column4 FROM `dbMyDataBase`.`tblMyTable` WHERE `tblMyTable`.`Column2` = 'UniqueValueOfTheKey' ;; / * mySQL 5.6 * /