En MySQL, ¿puedo copiar una fila para insertarla en la misma tabla?

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

Solo quiero copiar una fila para insertarla en la misma tabla (es decir, quiero duplicar una fila existente en la tabla) pero quiero hacer esto sin tener que enumerar todas las columnas después de "seleccionar", porque esta tabla tiene Demasiadas columnas.

Pero cuando hago esto, me sale el error:

Entrada duplicada 'xxx' para la clave 1

Puedo manejar esto creando otra tabla con las mismas columnas que un contenedor temporal para el registro que quiero copiar:

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;

¿Hay una manera más simple de resolver esto?

lina
fuente
Solo tengo un comentario sobre los valores codificados para la clave. Haría algo como max(oldtable.id) + oldtable_temp.keyesto para asegurarme de que los identificadores se incrementen y sean únicos.
Guy Mograbi
Posible duplicado de Duplicar / Copiar registros en la misma tabla MySQL
Organic Advocate
@OrganicAdvocate esto tiene más respuestas y más puntos de vista que esa pregunta
Drew

Respuestas:

189

Utilicé la técnica de Leonard Challis con algunos cambios:

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;

Como tabla temporal, nunca debe haber más de un registro, por lo que no tiene que preocuparse por la clave principal. Establecerlo como nulo permite a MySQL elegir el valor en sí mismo, por lo que no hay riesgo de crear un duplicado.

Si desea estar súper seguro de que solo está insertando una fila, puede agregar LIMIT 1 al final de la línea INSERT INTO.

Tenga en cuenta que también agregué el valor de la clave primaria (1 en este caso) a mi nombre de tabla temporal.

Severo...
fuente
3
Esta solución es correcta (en contraste con otras que obtuvieron votos) ya que le permite a MySQL elegir el valor de la clave primaria.
Jan Hettich
1
Aunque no funcionará exactamente como se debe a los nombres de tabla temporales inconsistentes ( tmptable_1vs. tmptable)
Kieran Tully
9
¿Cómo puede una clave primaria ser nula?
Imran Shafqat
55
Si es nulo, se le asigna automáticamente el siguiente número de AI cuando se inserta.
Grim ...
3
IMRAN: bien puede preguntar. Pensé que quizás el campo de identificación de la tabla temporal no se convirtió en un PK automáticamente (estoy bastante seguro de que SQL Server no lo hace en estas circunstancias), pero lo es. Necesitaba hacer ALTER TABLE tmptable_1 MODIFY primarykeyINT NULL; después de la primera línea para hacer que la solución funcione
DJDave
61

Actualización 07/07/2014 - La respuesta basada en mi respuesta, por Grim ... , es una mejor solución, ya que mejora mi solución a continuación, por lo que sugeriría usar eso.

Puede hacerlo sin enumerar todas las columnas con la siguiente sintaxis:

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;

Puede decidir cambiar la clave principal de otra manera.

LeonardChallis
fuente
16
Esta es básicamente la misma solución que el OP ya había proporcionado para su propio problema, aunque con tablas temporales reales y un patrón de creación ligeramente más limpio. Creo que el OP solicitó un mejor enfoque de lo que ya estaban usando, no una limpieza de su sintaxis existente. Realmente no entiendo todos los votos a favor de esto.
Sepster
Gracias. Funciona bien con la función dinámica
Sonal Khunt
¿Es necesario eliminar el tmptable una vez que este proceso ha finalizado?
SSH Este
"De forma predeterminada, MySQL elimina todas las tablas temporales cuando finaliza la conexión de su base de datos. Aún así, desea eliminarlas en el medio y luego lo hace emitiendo el comando DROP TABLE". Más aquí
LeonardChallis
Dado que creó el tmptable, no necesita agregar la WHERE primarykey = 2declaración para la última línea también. (Es decir, solo INSERT INTO table SELECT * FROM tmptable.)
Marcus
42

¿Asumo que quieres que el nuevo disco tenga uno nuevo primarykey? Si primarykeyes AUTO_INCREMENTasí, simplemente haz esto:

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

... donde col1, col2, col3, ...están todas las columnas de la tabla, excepto primarykey .

Si no es una AUTO_INCREMENTcolumna y desea poder elegir el nuevo valor primarykey, es similar:

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

... donde 567está el nuevo valor para primarykey.

Jordan Running
fuente
41
¿Cómo es que esto es votado 7 veces cuando ignora la pregunta? ... pero no quiero enumerar todas las columnas después de "seleccionar", porque esta tabla tiene demasiadas columnas ...
LeonardChallis
77
-1 ya que esto es precisamente lo que el OP quiere evitar. Lea la pregunta, o al menos ofrezca una respuesta como "esta es la única forma posible".
devios1
55
Porque a veces la pregunta en sí es incorrecta. :) Duplicar filas sin alterar el contenido aumenta la redundancia. Debería recomendarse cambiar la estructura de la base de datos para minimizar la redundancia, si es posible.
Torben
55
El hecho de que no sea correcto en las prácticas normales no lo hace incorrecto. Hay muchas ocasiones en que las mejores prácticas estándar no se aplican. Ejemplo: la base de datos representa documentos y un usuario debe conservar una copia de un documento antes de realizar cambios.
ima747
66
Porque es posible que aterrice en esta página sin querer exactamente lo mismo que el OP
jx12345
13

Casi lo tuvo con su primera consulta, solo necesita especificar las columnas, de esa manera puede excluir su clave principal en la inserción, lo que promulgará el incremento automático que probablemente tenga en la tabla para crear automáticamente una nueva clave primaria para el entrada.

Por ejemplo, cambie esto:

insert into table select * from table where primarykey=1

A esto:

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

Simplemente no incluya la columna de clave primaria en la lista de columnas para INSERT o para las partes SELECT de la consulta.

Braeden Black
fuente
1
¿hay alguna manera de extraer la mayoría de las columnas a través de la instrucción select pero actualizar una de ellas manualmente en el comando de inserción? como insert into table ("val1", col2, col3) select col2, col3 from table where primarykey = 1o algo similar?
anon58192932
1
¡Lo encontré! Copie los valores de una fila, pero agregue uno de sus propios valores a la instrucción de inserción: stackoverflow.com/questions/23971078/…
anon58192932
1
Lo siento, se acaba de notificar sus preguntas, me alegro de haberlo encontrado, esa es la forma
Braeden Black
9

También puede intentar volcar la tabla, encontrar el comando de inserción y editarlo:

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

El --skip-extended-insertle da un comando de inserción por fila. Luego puede encontrar la fila en su editor de texto favorito, extraer el comando y alterar la clave primaria a "predeterminada".

donothings exitosamente
fuente
2
+1 de mi parte ya que este es un buen enfoque "fuera de la caja" que en realidad puede ser útil fuera del tiempo de ejecución, en algunas circunstancias. Pero principalmente es la primera respuesta que en realidad aborda la pregunta del OP y no solo modifica sintácticamente la solución que ya ofrece el OP.
Sepster
6

Este procedimiento supone que:

  • no tienes _duplicate_temp_table
  • tu clave principal es int
  • tienes acceso para crear tabla

Por supuesto, esto no es perfecto, pero en ciertos casos (probablemente la mayoría) funcionará.

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
fuente
1
+1 No lo he confirmado, workspero el enfoque es sólido y tiene valor porque es único aquí y en realidad aborda la pregunta del OP.
Sepster
5

Esto se puede lograr con algo de creatividad:

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;

Esto dará como resultado que la nueva fila obtenga una identificación con incremento automático en lugar de la identificación de la fila seleccionada.

curmil
fuente
¡Esta debería ser la respuesta aceptada!
Felipe Desiderati
5

Si el campo de clave principal de su tabla es un campo de incremento automático, puede usar la consulta con columnas. Por ejemplo, su tabla llamada test_tbltiene 3 campos como id, name, age. ides un campo de clave principal y un incremento automático, por lo que puede usar la siguiente consulta para duplicar la fila:

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

Esta consulta da como resultado la duplicación de cada fila.


Si el campo de clave principal de su tabla no es un campo de incremento automático, puede usar el siguiente método:

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

El resultado de esta consulta es una fila duplicada de id=19insertada como id=20.

usuario2595171
fuente
Esa es la mejor respuesta es no, el caso es bastante sencillo: INSERT INTO tableName( fieldName1, fieldName2, fieldName3) SELECT fieldName1, fieldName2, fieldName3DE tableNameDONDE 1 (para copiar todos ellos a la vez)
jakubplus
Secundada: esta respuesta es sucinta y en el espíritu de "Copiar" una fila.
user37309
4

fila de clonación con campos de actualización y valor de incremento automático

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
fuente
@Torben Marque la marca a la izquierda de la pregunta (márquela como aceptada) para que todos sepan que funcionó para usted.
HosseyNJF
3

Algunos de los siguientes fueron extraídos de este sitio. Esto es lo que hice para duplicar un registro en una tabla con cualquier número de campos:

Esto también supone que tiene un campo AI al comienzo de la tabla

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
fuente
3

Utilicé la técnica de Grim con un pequeño cambio: si alguien que busca esta consulta es porque no puede hacer una consulta simple debido a un problema de clave principal:

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

Con mi instalación de MySql 5.6.26, la clave no es anulable y produce un error:

#1048 - Column 'primakey' cannot be null 

Entonces, después de crear una tabla temporal, cambio la clave principal para que sea anulable.

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
fuente
alternativamente, en las nuevas versiones de mariadb / mysql, la clave primaria se puede establecer en 0, lo que permite que el incremento automático funcione cuando se inserta.
Shelbypereira
2

Podría llegar tarde en esto, pero tengo una solución similar que me ha funcionado.

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

De esta manera, no necesito crear una tabla temporal, etc. Como la fila se copia en la misma tabla, la Max(PK)+1función se puede usar fácilmente.

Vine buscando la solución de esta pregunta (había olvidado la sintaxis) y terminé haciendo mi propia consulta. Es curioso cómo las cosas funcionan algunas veces.

Saludos

echo_salik
fuente
2

Si la clave primaria es Incremento automático, solo especifique cada campo excepto la clave primaria.

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

Veneno Fedy
fuente
2

Actualicé la solución de @ LeonardChallis ya que no funcionó para mí como ninguna de las otras. Eliminé las WHEREcláusulas y SET primaryKey = 0la tabla temporal para que MySQL se incremente automáticamente como la clave principal

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

Por supuesto, esto es para duplicar todas las filas de la tabla.

D4V1D
fuente
2

Yo usaría a continuación,

insert into ORDER_ITEM select * from ORDER_ITEM where ITEM_NUMBER =123;
Ishan Liyanage
fuente
1
Esto no funciona si ITEM_NUMBER es su clave principal, lo cual es probable en esta situación.
Billy Pilgrim
2

Utilicé en mi base de datos Koha para insertar elementos duplicados con el prefijo 'C' en la columna de código de barras :

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

Solo tenía que hacer esto y esta era mi solución manual:

  1. En phpmyadmin , marque la fila que desea copiar
  2. En la parte inferior de las operaciones de resultado de la consulta, haga clic en 'Exportar'
  3. En la página siguiente marque 'Guardar como archivo' y luego haga clic en 'Ir'
  4. Abra el archivo exportado con un editor de texto, encuentre el valor del campo primario y cámbielo a algo único.
  5. De vuelta en phpmyadmin, haga clic en la pestaña 'Importar' , ubique el archivo para importar el archivo .sql en Examinar , haga clic en 'Ir' y se debe insertar la fila duplicada.

Si no sabe cuál es el campo PRIMARIO , mire hacia atrás en su página de phpmyadmin , haga clic en la pestaña 'Estructura' y en la parte inferior de la página debajo de 'Índices' le mostrará qué 'Campo' tiene un 'Nombre de clave' valor 'PRIMARIO' .

Es un largo camino, pero si no desea lidiar con el marcado y solo necesita duplicar una sola fila, listo.

usuario27068
fuente
Agradable, responde a la operación de una manera innovadora. Obviamente, no funciona para todos los casos, como blobs y datos geoespaciales, pero es bastante fácil de lograr y funciona para esos cambios de bola extraños.
Strixy
1

Esta solución mostrada anteriormente funciona perfecto también para filas seleccionadas. Por ejemplo, estoy creando filas de demostración para mi proyecto nice2work, y esto funciona perfectamente.

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
fuente
0

Perdón por el necropost, pero esto es lo que encontré con google y desde que encontré esto útil pero problemático, quería aportar una modificación importante para cualquier otra persona que desentierre esto.

En primer lugar, estoy usando SQL Server, no MySQL, pero creo que debería funcionar de manera similar. Utilicé la solución de Leonard Challis porque era más simple y satisfacía la necesidad, sin embargo, hay un problema con esto: si simplemente toma el PK y lo incrementa en 1, entonces, ¿qué sucede si ha agregado otros registros desde que se agregó la fila en cuestión? . Decidí que era mejor dejar que el sistema manejara el incremento automático de la PK, así que hice lo siguiente:

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

Creo que esto funcionaría de manera similar en MySQL, pero no puedo probar esto, lo siento

maxx233
fuente
1
respuesta totalmente bakwaas
AsadYarKhan
0

Sé que es una vieja pregunta, pero aquí hay otra solución:

Esto duplica una fila en la tabla principal, suponiendo que la clave primaria es de incremento automático, y crea copias de datos de tablas vinculadas con la nueva identificación de la tabla principal.

Otras opciones para obtener nombres de columna:
-MOSTRAR COLUMNAS DE tablename; (Nombre de columna: Campo)
-DESCRIBIR tablename (Nombre de columna: Campo)
-SELECCIONAR nombre_columna DESDE información_esquema.columnas DONDE nombre_tabla = 'nombre_tabla' (Nombre de columna: nombre_columna)

//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__);
}
Pablo
fuente
0

max233 ciertamente estaba en el camino correcto, al menos para el caso de autoincremento. Sin embargo, no haga la TABLA DE ALTERACIÓN. Simplemente establezca el campo de incremento automático en la tabla temporal en NULL. Esto presentará un error, pero ocurrirá el siguiente INSERT de todos los campos en la tabla temporal y el campo automático NULL obtendrá un valor único.

usuario3067083
fuente
0

Crear una tabla

    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';

Insertar una fila

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

Insertar fila de clones arriba

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;

Prueba

SELECT * FROM `sample_table`;
Abdullah Aydın
fuente
Nota: Si obtiene un error (# 1048) use '' en lugar de NULL
Abdullah Aydın
¿Soy solo yo o es exactamente lo que el OP no quería? (Es decir, agregar manualmente cada columna a la consulta).
Byson
Tienes razón, acabo de leer la frase de OP "SOLO quiero copiar una fila para insertarla en la misma tabla", quizás, de todos modos, esto todavía es útil para "Duplicar la entrada 'xxx' para la clave ???" error ^^
Abdullah Aydın
0

Aquí hay una respuesta que encontré en línea en este sitio Describe cómo hacer lo anterior 1 Puede encontrar la respuesta en la parte inferior de la página. Básicamente, lo que debe hacer es copiar la fila que se copiará en una tabla temporal guardada en la memoria. Luego, cambia el número de la clave principal mediante la actualización. Luego lo vuelve a insertar en la tabla de destino. Luego dejas caer la mesa.

Este es el código para ello:

CREAR rescueteamMOTOR DE TABLA TEMPORAL = SELECCIONAR MEMORIA * DE fitnessreport4DONDE rID = 1; fila # 1 afectada. ACTUALIZAR rescueteamSET rID = Nulo DONDE rID = 1; fila # 1 afectada. INSERTAR EN fitnessreport4SELECCIONAR * DESDE rescueteam; fila # 1 afectada. DROP TABLE rescueteam# MySQL devolvió un conjunto de resultados vacío (es decir, cero
filas).

Creé la tabla temporal de equipo de rescate. Copié la fila de mi tabla original fitnessreport4. Luego configuré la clave principal para la fila en la tabla temporal como nula para poder copiarla de nuevo a la tabla original sin obtener un error de clave duplicada. Intenté este código ayer por la noche y funcionó.

usuario2363682
fuente
0

Esta es una solución adicional a la respuesta de "Grim ..." Ha habido algunos comentarios sobre que tiene una clave primaria como nula. Algunos comentarios al respecto no funcionan. Y algunos comentarios sobre soluciones. Ninguna de las soluciones funcionó para nosotros. Tenemos MariaDB con la tabla InnoDB.

No pudimos establecer la clave primaria para permitir nulo. El uso de 0 en lugar de NULL condujo a un error de valor duplicado para la clave primaria. SET SQL_SAFE_UPDATES = 0;Tampoco funcionó.

La solución de "Grim ..." funcionó SI cambiamos nuestra CLAVE PRIMARIA a ÚNICA

Simón
fuente
-1

Solo quería publicar mi fragmento de código PHP, porque creo que la forma en que recopilo las columnas es un poco más limpia en el código que los ejemplos anteriores. Además, esto muestra cómo podría alterar fácilmente un campo, en este caso agregando una cadena. Pero también puede reemplazar un campo de clave externa con el registro recién agregado, en caso de que desee copiar también algunos registros secundarios.

  // 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
fuente
-2

Para una solución muy simple, puede usar PHPMyAdmin para exportar la fila como un archivo CSV y luego simplemente importar el archivo CSV modificado. Edición de la columna ID / clave principal para no mostrar ningún valor antes de importarlo.

SELECT * FROM table where primarykey=1

Luego, al final de la página:

ingrese la descripción de la imagen aquí

Donde dice "Exportar" simplemente exporte, luego edite el archivo csv para eliminar el valor de la clave primaria, de modo que esté vacío, y luego simplemente impórtelo a la base de datos, se asignará una nueva clave primaria en la importación.

Conceder
fuente