2009-10-27 37 views
5

Tengo una tabla y quiero duplicar filas específicas en la tabla. Sé que esta no es la mejor manera de hacer las cosas, pero estamos buscando una solución rápida.Duplicar un registro en MySQL

Aquí hay algo más difícil de lo que pensé inicialmente, todo lo que tengo que hacer es copiar un registro completo en un nuevo registro en una tabla de incremento automático en MySql sin la necesidad de especificar cada campo. Esto se debe a que la tabla puede cambiar en el futuro y puede romper la duplicación. Estaré duplicando los registros de MySQL de PHP.

Es un problema porque en una consulta 'SELECT *' MySql intentará copiar la ID del registro que se está copiando, lo que generará un error de ID duplicado.

Esto bloquea: INSERT INTO customer SELECT * FROM customer WHERE customerid=9181. También bloquea INSERT INTO customer (Field1, Field2, ...) SELECT Field1, Field2, ..... FROM customer WHERE customerid=9181.

¿Hay alguna manera de hacerlo desde PHP o MySQL?

Respuesta

12

Finalmente encontré este código. Estoy seguro de que ayudará a las personas en el futuro. Asi que aqui esta.

function DuplicateMySQLRecord ($table, $id_field, $id) { 
    // load the original record into an array 
    $result = mysql_query("SELECT * FROM {$table} WHERE {$id_field}={$id}"); 
    $original_record = mysql_fetch_assoc($result); 

    // insert the new record and get the new auto_increment id 
    mysql_query("INSERT INTO {$table} (`{$id_field}`) VALUES (NULL)"); 
    $newid = mysql_insert_id(); 

    // generate the query to update the new record with the previous values 
    $query = "UPDATE {$table} SET "; 
    foreach ($original_record as $key => $value) { 
    if ($key != $id_field) { 
     $query .= '`'.$key.'` = "'.str_replace('"','\"',$value).'", '; 
    } 
    } 
    $query = substr($query,0,strlen($query)-2); # lop off the extra trailing comma 
    $query .= " WHERE {$id_field}={$newid}"; 
    mysql_query($query); 

    // return the new id 
    return $newid; 
} 

Aquí está el enlace al artículo http://www.epigroove.com/posts/79/how_to_duplicate_a_record_in_mysql_using_php

+1

Intenté usarlo y hay un error con la función foreach. –

0

¿Qué tal copiar las filas en una tabla temporal y luego volver a la tabla de clientes? Creo que eso forzaría a mysql a darle una nueva identificación de autoincrement, especialmente con la segunda versión de la consulta que publicaste.

1

¿Qué hay de

insert into test.abc select null, val1, val2 from test.abc where val2 = some_condition; 

parece funcionar para mí de esa manera. Sustituye tu mesa, campos, condición, por supuesto.

El nulo permite que el DB genere el ID de incremento automático para usted.

+0

El inconveniente es que tengo que codificar val1, val2, etc. ¿Hay alguna forma de no tener este código rígido? – Pasta

+0

Sí, ese es el inconveniente. Probablemente optaría por determinar programáticamente los nombres de columna y construir la declaración de inserción apropiada sobre la marcha para evitar la codificación difícil de las columnas. "SHOW COLUMNS FROM table" le proporcionará esa información y hay una columna 'Field' y 'Key' en los resultados de esa llamada. Si bien no soy un desarrollador de PHP, sospecho que puede hacer la llamada para recuperar los nombres de las columnas, descartar los campos de clave no primaria y construir la instrucción de inserción a partir de eso. No lo he probado, pero sospecho que esto funcionaría. – itsmatt

0

Dos publicaciones hasta el momento, y aquí hay una tercera opción: en PHP, determine dinámicamente los campos en su tabla. O bien, puede hacer una lista de matriz de los campos que "codifica", mantener a mano para reflejar la tabla. Su consulta resultante no usará *.

1

Opciones:

  1. evitar el uso del comodín *, y especificar todas las columnas a sí mismo. Pero usted dice que se espera que la tabla cambie en el futuro y esta no es una solución viable para su caso.

  2. Analiza las columnas de la definición de tabla actual (usando DESCRIBE o consultando INFORMATION_SCHEMA.COLUMNS). Utilice esta información sobre metadatos para generar la consulta, omitiendo la columna de clave principal de incremento automático.

  3. Realice la consulta SELECT *, recupere la fila en su aplicación y luego elimine la columna de incremento automático de la misma. Luego use esa tupla para construir una declaración INSERT.

En resumen, tiene un requisito complejo para adaptarse a los metadatos cambiantes. Eso probablemente no se puede hacer en una sola consulta.

0

Si conoce el nombre de la columna de clave principal de la tabla (y supongo que lo hace porque es en la cláusula where de todos modos), Creo que podrías hacer esto:

Editar - Olvidé que MySQL no admite seleccionar ... en. Esto debería funcionar en su lugar

create new_table 
select * 
from customer 
where customerid = 9181 

alter table new_table 
drop column customerid 

insert into customer 
select null, * 
from new_table 

drop table new_table