Código PHP:
<?php
/**
* Utiliza una variable $xRows para seleccionar e insertar las filas en paquetes.
* Cada paquete de $xRows inserts se hace dentro de un bloque de transacciones de manera que en caso de fallo se ejecuta un rollback dejando todo como estaba antes.
* Para cada paquete de lectura / escritura, dado que la lectura se hace en $xSourceDB y la escritura en $xDestinationDB se ejecuta la función USE DB para pasar de una dba otra.
* El funcionamiento general es: leer tabla origen en paquetes de $xRows filas, cambiar de db, insertar las $xRows filas.
*
* CONSIDERACIONES:
* 1. Hemos de estar conectados a la db.
* 2. Se deben tener los permisos de select, insert, drop y alter EN AMBAS BASES DE DATOS.
* 3. Se recomienda ejecutar siempre en el mismo server donde está la db, de lo contrario los tiempos de conexión se disparan.
* 4. La tabla destino debe existir.
*
*
* @param string $xSourceTable tabla origen
* @param string $xSourceDB db origen
* @param string $xDestinationTable tabla destino
* @param string $xDestinationDB db destino
* @param string $xRows filas por operación
* @return el número de operaciones que ha realizado para copiar la tabla
*/
function moveTable($xSourceTable, $xSourceDB, $xDestinationTable, $xDestinationDB, $xRows = 1000){
//Obtenemos el max_execution_time
$xMET = ini_get("max_execution_time");
//Obtener el total de filas de la tabla
$sql = "SELECT COUNT(*) as total FROM $xSourceDB.$xSourceTable;";
if(!$xQuery = mysql_query($sql)) return false;
$fetch = mysql_fetch_assoc($xQuery);
if(!$xTotalRows = $fetch['total']) return false;
mysql_free_result($xQuery);
//Las posibles filas restantes
$xResto = $xTotalRows%$xRows;
//Con el total de filas, hacemos las selects paginando por $xRows
$z = 1;
for($x=0;$x<=($xTotalRows-$xResto);$x+=$xRows){
//Obtener los datos desde el origen
$xSqlOrigen = "SELECT * FROM $xSourceDB.$xSourceTable LIMIT $x,".($x==$xTotalRows-$xResto?$xTotalRows:$xRows).";";
$xBegin = mysql_query("BEGIN");
$xUse = mysql_query("USE $xSourceDB;");
if(!$xQuery = mysql_query($xSqlOrigen)) return false;
//El total de campos * Total fields in query
$xNumFields = mysql_num_fields($xQuery);
while($fetch = mysql_fetch_array($xQuery)){
$xInsert = "INSERT INTO $xDestinationDB.$xDestinationTable VALUES(";
for($i=0;$i<$xNumFields;$i++)
$xInsert .= ($fetch[$i]!=""?(is_string($fetch[$i])?"'".$fetch[$i]."'":$fetch[$i]):"''").",";
//Quitar la ultima coma
$xInsert = substr($xInsert, 0, -1);
$xInsert .= ");";
$xUse = mysql_query("USE $xDestinationDB;");
if(!$xQueryInsert = mysql_query($xInsert)) {
$xRollback = mysql_query("ROLLBACK");
$error = new Error("moveTale(): Fallo en el insert, rollback en operación $z. ".mysql_error());
die("Fallo en el insert, rollback en operación $z. ".mysql_error());
}
$z++;
//Aumento el tiempo de ejecución para evitar timeouts
ini_set("max_execution_time", $xMET);
}
//Liberar resultados
mysql_free_result($xQuery);
}
//Todo ok hasta ahora
$xCommit = mysql_query("COMMIT");
//Dejo el sistema como estaba * Leave everything as it was before
if(!$xQuery = mysql_query("DROP TABLE `$xSourceDB.`$xSourceTable;")) $xRollback = mysql_query("ROLLBACK");
$xUse = mysql_query("USE $xSourceDB;");
ini_set("max_execution_time", $xMET);
return $z;
}
/**
* EJEMPLO DE USO * USAGE EXAMPLE
*/
$xSourceTable = "usuarios";
$xSourceDB = "gestion";
$xDestinationTable = "usuarios.old";
$xDestinationDB = "archivo";
$xRows = 500;
if(!$resultado = dbHandler::moveTable($xSourceTable, $xSourceDB, $xDestinationTable, $xDestinationDB, $xRows)) $msg = "<h3>Imposible mover tabla $xSourceTable a archivo!.</h3>";
?>