it-swarm.com.de

Wie kopiere ich eine Zeile und füge sie mit einem Autoincrement-Feld in MySQL in dieselbe Tabelle ein?

Ich habe einen Tisch Egg. Ich versuche, eine Zeile mit der Autoincrement-Spalten-ID = 1 zu kopieren und die Daten mit der Zeilen- und Spalten-ID = 2 in dieselbe Tabelle einzufügen.

Verwenden von MySQL. Wie kann ich dies in einer einzelnen Abfrage tun? Bitte helfen Sie

203
Navdroid

Benutze INSERT ... SELECT:

insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1

wobei c1, c2, ... alle Spalten außer id sind. Wenn Sie explizit mit id von 2 einfügen möchten, fügen Sie dies in Ihre INSERT-Spaltenliste und in Ihr SELECT ein:

insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1

Im zweiten Fall müssen Sie sich natürlich um ein mögliches Duplikat von id von 2 kümmern.

308
mu is too short

IMO scheinen die Besten SQL-Anweisungen nur zum Kopieren dieser Zeile zu verwenden, während sie gleichzeitig nur auf die Spalten verweisen, 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:

  • Die SQL-Anweisungen 2 erwähnen nur die Felder, die während des Klonvorgangs geändert werden müssen. Sie kennen andere Bereiche nicht oder kümmern sich nicht darum. Die anderen Felder gehen unverändert mit. Dies macht die SQL-Anweisungen einfacher zu schreiben, leichter zu lesen, leichter zu warten und erweiterbarer.
  • Es werden nur normale MySQL-Anweisungen verwendet. Es werden keine weiteren Tools oder Programmiersprachen benötigt.
  • Ein vollständig korrekter Datensatz wird in your_table in einer atomaren Operation eingefügt.
42
parvus

Angenommen, die Tabelle 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)
14
Vijay

Dies hat geholfen und es werden BLOB/TEXT-Spalten unterstützt.

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;
9
Petr Hladík

Für eine schnelle, saubere Lösung, bei der Sie keine Spalten benennen müssen, können Sie eine vorbereitete Anweisung wie folgt verwenden: https://stackoverflow.com/a/23964285/292677

Wenn Sie eine komplexe Lösung benötigen, um dies häufig zu tun, können Sie das folgende 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.

7
curmil

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
2
RBILLC

Sie können auch '0' als Wert für die automatische Inkrementierung der Spalte übergeben. Der richtige Wert wird verwendet, wenn der Datensatz erstellt wird. 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)

2
Mark Pruce
insert into MyTable(field1, field2, id_backup)
    select field1, field2, uniqueId from MyTable where uniqueId = @Id;
2
IR.Programmer

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, wenn immer möglich, gespeicherte Prozeduren verwende (um anderen Programmierern, die mit Datenbanken nicht allzu vertraut sind, das Leben zu erleichtern), wird das Problem behoben, dass Prozeduren jedes Mal aktualisiert werden müssen, wenn Sie einer Tabelle ein neues Feld hinzufügen.

Außerdem wird sichergestellt, dass neue Felder, die Sie einer Tabelle hinzufügen, sofort in der Protokolltabelle angezeigt werden, ohne dass Sie Ihre Datenbankabfragen aktualisieren müssen (es sei denn, Sie haben explizit Felder festgelegt).

Warnung: Sie sollten sicherstellen, dass Sie beide Tabellen gleichzeitig mit neuen Feldern versehen, damit die Feldreihenfolge gleich bleibt. Andernfalls treten seltsame Fehler auf. Wenn Sie der einzige sind, der Datenbankschnittstellen schreibt UND sehr vorsichtig sind, funktioniert dies sehr gut. Ansonsten bleiben Sie beim Benennen aller Ihrer Felder.

Hinweis: Wenn Sie nicht an einem Solo-Projekt arbeiten, müssen Sie sicher sein, dass keine anderen daran arbeiten, um alle Feldnamen explizit aufzulisten und Ihre Protokollanweisungen zu aktualisieren, wenn sich Ihr Schema ändert. Diese Abkürzung ist wahrscheinlich nicht die langfristigen Kopfschmerzen wert, die sie verursachen kann ... insbesondere auf einem Produktionssystem.

0
Privateer

Speichern Sie die Zeile, in die Sie SQL schreiben möchten, und verwenden Sie dann das generierte SQL, abzüglich der ID-Spalte, um es wieder zu importieren.

0
Claire

Ich habe nach der gleichen Funktion gesucht, benutze aber kein MySQL. Ich wollte ALLE Felder kopieren, außer natürlich den Primärschlüssel (id). Dies war eine einmalige Abfrage, die in keinem Skript oder Code verwendet werden sollte.

Ich habe mich mit PL/SQL zurechtgefunden, aber ich bin mir sicher, dass jedes andere SQL IDE das kann. Ich habe ein Basic gemacht

SELECT * 
FROM mytable 
WHERE id=42;

Dann exportieren Sie es in eine SQL-Datei, in der ich das finden konnte

INSERT INTO table (col1, col2, col3, ... , col42) 
VALUES (1, 2, 3, ..., 42);

Ich habe es gerade bearbeitet und benutzt:

INSERT INTO table (col1, col2, col3, ... , col42) 
VALUES (mysequence.nextval, 2, 3, ..., 42);
0
SabineA
 INSERT IN `dbMyDataBase`.`tblMyTable` 
 (
` IdAutoincrement`, 
 `Column2`, 
` Column3`, 
 `Column4` 
) 
 
 SELECT 
 NULL, 
` Column2`, 
 `Column3`, 
 'CustomValue' AS Column4 
 FROM `dbMyDataBase`.`tblMyTable` 
 WHERE` tblMyTable`.`Column2` = 'UniqueValueOfTheKey' 
; 
/* mySQL 5.6 */
0