solo - Duplicar/Copiar registros en la misma tabla MySQL
duplicar registros en una consulta sql server (9)
He estado buscando por un tiempo pero no puedo encontrar una solución fácil para mi problema. Me gustaría duplicar un registro en una tabla, pero, por supuesto, la clave primaria única debe actualizarse.
Tengo esta consulta:
INSERT INTO invoices
SELECT * FROM invoices AS iv WHERE iv.ID=XXXXX
ON DUPLICATE KEY UPDATE ID = (SELECT MAX(ID)+1 FROM invoices)
el problema es que esto simplemente cambia el ID
de la fila en lugar de copiar la fila. Sabe alguien cómo arreglar esto ?
// edit: me gustaría hacer esto sin escribir todos los nombres de campo porque los nombres de campo pueden cambiar con el tiempo.
La forma en que suelo hacerlo es usar una tabla temporal. ¡Probablemente no sea computacionalmente eficiente, pero parece funcionar bien! Aquí estoy duplicando el registro 99 en su totalidad, creando el registro 100.
CREATE TEMPORARY TABLE tmp SELECT * FROM invoices WHERE id = 99;
UPDATE tmp SET id=100 WHERE id = 99;
INSERT INTO invoices SELECT * FROM tmp WHERE id = 100;
Espero que funcione bien para ti!
La respuesta de Alex necesita cierto cuidado (por ejemplo, bloqueo o una transacción) en entornos multicliente.
Suponiendo que el campo AUTO ID
es el primero en la tabla (un caso habitual), podemos hacer uso de transacciones implícitas.
CREATE TEMPORARY TABLE tmp SELECT * from invoices WHERE ...; ALTER TABLE tmp drop ID; # drop autoincrement field # UPDATE tmp SET ...; # just needed to change other unique keys INSERT INTO invoices SELECT 0,tmp.* FROM tmp; DROP TABLE tmp;
De los documentos de MySQL:
Usando AUTO_INCREMENT: También puede asignar explícitamente NULL o 0 a la columna para generar números de secuencia.
Ligera variación, la principal diferencia es establecer el campo de la clave principal ("varname") en nulo, lo que produce una advertencia pero funciona. Al establecer la clave primaria en nulo, el autoincremento funciona al insertar el registro en la última declaración.
Este código también limpia los intentos previos, y se puede ejecutar más de una vez sin problemas:
DELETE FROM `tbl` WHERE varname="primary key value for new record";
DROP TABLE tmp;
CREATE TEMPORARY TABLE tmp SELECT * FROM `tbl` WHERE varname="primary key value for old record";
UPDATE tmp SET varname=NULL;
INSERT INTO `tbl` SELECT * FROM tmp;
Necesitaba esto también; Mi solución fue utilizar SQLYOG (versión gratuita) para exportar el registro deseado como SQL (crea una inserción).
A continuación, edité esto para eliminar la identificación, ya que debe ser generada automáticamente y luego copié la inserción en SQLYog para ejecutarla. Esto fue indoloro Creo que muchas otras GUI de MySQL pueden hacer esto también.
Esto me proporciona un registro que puedo usar para fines de prueba en un sistema en vivo.
Ahora también tengo este inserto para reutilizar, ya que la tabla se reescribe todos los días.
Solo quería extender la excelente respuesta de Alex para que sea apropiado si desea duplicar un conjunto completo de registros:
SET @x=7;
CREATE TEMPORARY TABLE tmp SELECT * FROM invoices;
UPDATE tmp SET id=id+@x;
INSERT INTO invoices SELECT * FROM tmp;
¡Solo tenía que hacer esto y encontré que la respuesta de Alex era un punto de partida perfecto !. Por supuesto, debe establecer @x en el número de fila más alto de la tabla (estoy seguro de que podría obtenerlo con una consulta). Esto solo es útil en esta situación tan específica, así que tenga cuidado de usarlo cuando no desee duplicar todas las filas. Ajuste las matemáticas según sea necesario.
Su enfoque es bueno, pero el problema es que utiliza "*" en lugar de alistar los nombres de los campos. Si coloca todos los nombres de columnas excep primary key, su script funcionará como charm en uno o muchos registros.
INSERT INTO invoices (iv.field_name, iv.field_name,iv.field_name ) SELECT iv.field_name, iv.field_name,iv.field_name FROM invoices AS iv WHERE iv.ID=XXXXX
Tengo un problema similar, y esto es lo que estoy haciendo
insert into Preguntas (`EncuestaID`, `Tipo` , `Seccion` , `RespuestaID` , `Texto` ) select ''23'', `Tipo`, `Seccion`, `RespuestaID`, `Texto` from Preguntas where `EncuestaID`= 18
Has estado Preguntas:
CREATE TABLE IF NOT EXISTS `Preguntas` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`EncuestaID` int(11) DEFAULT NULL,
`Tipo` char(5) COLLATE utf8_unicode_ci DEFAULT NULL,
`Seccion` int(11) DEFAULT NULL,
`RespuestaID` bigint(11) DEFAULT NULL,
`Texto` text COLLATE utf8_unicode_ci ,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=522 ;
Entonces, la ID
se incrementa automáticamente y también estoy usando un valor fijo (''23'') para `EncuestaID
Una respuesta tardía que conozco, pero sigue siendo una pregunta común, me gustaría agregar otra respuesta que funcionó para mí, con solo usar el insert into
de insert into
de una sola línea, y creo que es sencillo, sin crear ninguna tabla nueva ( ya que podría ser un problema con los permisos CREATE TEMPORARY TABLE
):
INSERT INTO invoices (col_1, col_2, col_3, ... etc)
SELECT
t.col_1,
t.col_2,
t.col_3,
...
t.updated_date,
FROM invoices t;
La solución está funcionando para la columna de identificación AUTO_INCREMENT
, de lo contrario, puede agregar una columna de ID
así como una declaración:
INSERT INTO invoices (ID, col_1, col_2, col_3, ... etc)
SELECT
MAX(ID)+1,
t.col_1,
t.col_2,
t.col_3,
... etc ,
FROM invoices t;
es realmente sencillo y sencillo, puede actualizar cualquier otra cosa en una sola línea sin ninguna segunda declaración de actualización para más adelante (por ejemplo, actualizar una columna de título con texto adicional o reemplazar una cadena por otra), también puede ser específico con qué exactamente lo que quiere duplicar, si todo es correcto, si es posible, puede hacerlo.
Usted SABE con certeza, que se activará la CLAVE DUPLICADA, por lo que puede seleccionar MAX (ID) +1 de antemano:
INSERT INTO invoices SELECT MAX(ID)+1, ... other fields ... FROM invoices AS iv WHERE iv.ID=XXXXX