A veces puede ser interesante ofrecer al usuario el poder actualizar datos de una base de datos MySQL utilizando como fuente un fichero *.csv generado por Excel
MySQL es capaz de importar datos no sólo a través de archivos con sentencias SQL, sino tambien desde ficheros CSV exportados desde una hoja de calculo como MS Excel a traves de la funcion LOAD DATA INFILE.
En este tutorial no veremos todas las posibilidades que la función ofrece. Nos centraremos en aquellas de uso más común, pero que se adaptan al 95% de las situaciones en que vayamos a encontrarnos. Para saber más sobre la misma podéis consultar el manual de MySQL
En la mayoría de los casos, la función tendrá un aspecto como éste:
LOAD DATA LOCAL INFILE “nombreArchivo” REPLACE INTO TABLE miTabla
FIELDS TERMINATED BY ‘,’ LINES TERMINATED BY ‘\n\r’ IGNORE 1 LINES (columna1,columna2)
?Qué significa todo esto? Vamos a verlo paso a paso:
LOAD DATA LOCAL INFILE “nombreArchivo”
MySQL tiene 2 caminos para leer el archivo .csv:
- Leerlo directamente el servidor
- Conectarse con el cliente y leerlo a través de él
La primera posibiliidad es muy rapida en su ejecución (Es el propio servidor el que ejecuta la operación), pero necesita de más permisos (FILE, por ejemplo, que no siempre está activado para usuarios normales).
En el segundo caso (gracias a la opcion LOCAL) MySQL crea una conexión con el cliente y, a través de ella, comienza a leer el archivo. El sistema es un poco más lento, pero a cambio no se necesitan permisos especiales tipo FILE. En este caso, sin embargo, es necesario que mysqld haya sido inciado con la opción --local-infile=1
Por lo tanto: LOAD DATA LOCAL INFILE indica que utilizaremos el segundo sistema
LOAD DATA LOCAL INFILE “nombreArchivo” REPLACE INTO TABLE tableName
La opción REPLACE (y su opuesta IGNORE) controlan la entrada de registros que tengan una clave ya existente en la tabla.
REPLACE provoca que el registro reemplace el ya existente.
IGNORE, en cambio, ignora el nuevo registro sin modificar el existente. Al utilizar en nuestro caso la opcion LOCAL éste es el valor definido por defecto, por lo que:
LOAD DATA LOCAL INFILE nombreArchivo IGNORE INTO TABLE miTabla
y:
LOAD DATA LOCAL INFILE nombreArchivo INTO TABLE miTabla
Son 2 sentencias identicas.
Opciones de separacion de datos:
1.- FIELDS/LINES TERMINATED BY:
Estas opciones nos permiten indicar qué simbolos son los que separan cada campo y linea, respectivamente, del archivo *.csv. Algunos ejemplos pueden ser:
- FIELDS TERMINATED BY ‘,’ (separados por comas)
- FIELDS TERMINATED BY ‘;’ (separados por punto y coma)
- FIELDS TERMINATED BY ‘\t’ (separados por tabulaciones)
Y para indicar el separador de cada linea:
LINES TERMINATED BY ‘\n\r’
2.- IGNORE XX LINES
Esta opcion permiteindicar si la(s) primera(s) linea(s) del fichero *.csv contiene algun otro tipo de informacion que no debe ser insertada en la tabla. El ejemplo mas habitual es cuando esta primera linea se utiliza en excel para mostrar los titulos de cada fila, en cuyo caso deberiamos escribir:
IGNORE 1 LINES
SUPUESTO PRACTICO
Como supuesto práctico hemos decidido que nuestro futuro usuario ya conoce que, al exportar desde Excel, debe utilizar punto y coma para separar cada campo y cada linea del fichero se corresponde con un registro en la tabla. Al mismo tiempo, hemos asumido que la primera fila incluye el titulo de cada columna y que la hoja de calculo contenia un campo de indice. Nuestro ejemplo tambien asumira que la hoja de calculo debe actualizar los registros actuales de la tabla (por lo que utilizaremos REPLACE)
Empezaremos creando el formulario que permitirá al usuario seleccionar el fichero csv:
Como veis, simplemente hemos creado el formulario y un input que permita al usuario seleccionar el fichero csv.
Vayamos ahora al lado servidor. En el mismo documento, insertaremos algo de PHP que procese el fichero seleccionado y lo inserte en la Base de datos La consulta base será algo como esto (de momento sólo debes cambiar el valor para “miTabla”):
LOAD DATA LOCAL INFILE nombreArchivo REPLACE INTO TABLE miTabla FIELDS TERMINATED BY ';' LINES TERMINATED BY '\r\n' IGNORE 1 LINES
Simplemente observad a continuación que el parametro nombreArchivo tiene como valor el equivalente al campo del formulario ‘csv’, que se corresponde con el nombre del input de nuestro formulario (Se ha intentado simplificar el código al máximo para centrarnos en la consulta)
if (isset($_POST['csv']){
uploadQuery="LOAD DATA LOCAL INFILE ".$csv." REPLACE INTO TABLE miTabla FIELDS TERMINATED BY';' LINES TERMINATED BY '\r\n' IGNORE 1 LINES";
mysql_query($uploadQuery) or die("error:".mysql_error());
}
Para poder verlo con más claridad (gracias por el comentario, Francis), podeis ulsar aqui y bajaros unos archivo de ejemplo
hola: me gustaria que me brindara un ejemplo ya terminado .. me interesa el tema …
mi proble ma es que tengo un monton de txt y quero pasarlos a mi base de datos mysql esto debe ser en linea
agradecere su ayuda ..
Algún Ejemplo????????
Hola Francis:
Este es uno de los tutoriales heredados del antiguo sitio y ha perdido algo de información en el camino (culpa del cambio de encoding)
Prometo actualizarlo en unos dÃas y puadjuntar algun ejemplo (¿alguien tiene tiempo libre para prestarme?)
Hola a todos estoy probando el ejemplo en el servidor local de mi compu pero al tratar de cargar el archivo csv, me sale este error error:File ‘C:WINDOWSTEMPphp264A.tmp’ not found (Errcode: 2) alguien sabe porque me sale eso
Hola Paco:
http://bugs.php.net/bug.php?id=7244
Prueba a cambiar ‘$csv’ por addslashes($csv)
No he leido el bug completo, pero puede ser una pista 8-)
Gracias por tu ayuda Andres, estoy utilizando el archivo ejemplo que se encuentra al final del tutorial y en vez de utilizar ‘$csv’ el codigo tiene if (isset($archivo)) {
$query = “LOAD DATA INFILE ‘”.$archivo.”‘ REPLACE INTO TABLE esmmug_load_data FIELDS TERMINATED BY ‘,’ LINES TERMINATED BY ‘\r\n’ IGNORE 1 LINES (id,nombre,edad)”;
mysql_query($query) or die(“error:”.mysql_error());
}
Hola me gustaria que me ayudaran al probar el ejemplo me marca este error:’’C:\WINDOWS\TEMP\php3.tmp’REPLACE INTO TABLE esmmug_load_data FIELDS TERMINATED ‘ at line 1 y ya estuve checando pero no se en donde este el error.
Ejecuto el siguiente script no me sale ningun error pero tampoco me sube a la base de datos los registros de excel, que sera??????????????? AYUDAAAAAA
Si utilizo la sentencia if (isset($_POST['csv']){.. no me ejecuta nada, en cambio si utilizo la sentencia if (isset($archivo){… me sale como error que la version de mysql no permite esta sentencia, ilustrenme por favor???
Paco prueba con lo siguiente, seguramente funcione:
if (isset($archivo)) {
$archivo=addslashes ($archivo);
$query = “LOAD DATA INFILE ‘â€.$archivo.â€â€˜ REPLACE INTO TABLE esmmug_load_data FIELDS TERMINATED BY ‘,’ LINES TERMINATED BY ‘\r\n’ IGNORE 1 LINES (id,nombre,edad)â€;
mysql_query($query) or die(â€error:â€.mysql_error());
}
hola, este post es de agosto y no se si lograre recibir respuesta, la cosa es k estoy intentando extraer la informacion de un excel para formar una tabla mysql. El script que ejecuto es el siguiente
use mydb;
LOAD DATA LOCAL INFILE
‘C:\\\\ejemploAS400.csv’
INTO TABLE sistemas
FIELDS TERMINATED BY ‘;’
LINES TERMINATED BY ‘\r\n’;
Funciona casi correctamente, el problema es cuando llega al 3er campo, fecha, en este campo excel formata la fecha asi Ej. 11/08/2001, mientras que mysql la forma asi Ej 2001-08-11, se os ocurre como hacer para que se entiendan?????
Agradeceria muchisimo las posibles ayudas
Hola Albert:
La pregunta es:
¿Inserta los campos aunque sea en dicho formato? Si lo hace, el problema no es importante: Sólo hay que darle formato a la salida (MySQL utiliza yyyy-mm-dd para almacenar fechas)
Tengo una aplicacion de java que necesito que haga lo mismo, pero es una aplicacion de escritorio, aplique la linea de codigo en mysql pero me dice que el resultset no regreso nada, me pueden ayudar porfa?
muchas gracias.
Tengo la misma inquietud de Albert y no logro hacer que el formato de Mysql yyyy-mm-dd entienda el de Excel que viene mm-dd-yyyy. Y para datetime ó timestamp? agregando la hora?
tengo un problema agradeceria la ayuda de alguien. tengo un archivo en excel csv y necesito pasar esa informacion a una base de datos mysql, si alguien me pudiera facilitar el codigo php se lo agradeceria mucho.
Olas el archivo load_data_infile_sample.zip ya no se encuentra alguien me lo podria pasar …
Hi, ayuda!! necesito alguna libreria para generar reporte excel a partir de dreamweaver cs5, si alguien sabe se lo agradeceria!!
me podrian dar un ejemplo completo les agradeceria su ayuda.
Tendria la bondad de arreglar el link del archivo de ejemplo que ya no esta… Saludos
Hola, el enlace no funciona para el archivo de ejemplo.
hola alguien me podria mandar el ejemplo o uno parecido?
xk el link esta roto, gracias
Tengo una tabla que tiene entre otros un campo numerico definido en un motor MYSQL 5.5 que al cargarla con la sentencia INFILE DATA LOCL…. a partir de un archivo csv generado desde excell me da un error 1366 Incorrect decimal value.
Me pueden ayudar a resolver la cuestion.
Desde ya les agradezco y les copio las sentencias SQL que ejecuto con el motor MYSQL para generar la tabla y cargar los datos.
– Table `TBCSV002`
– – —————————————————–
DROP TABLE IF EXISTS `TBCSV002` ;
SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS `TBCSV002` (
`TBCSV002_CLIENTE` INT(11) NOT NULL ,
`TBCSV002_CODIGO` CHAR(3) NOT NULL ,
`TBCSV002_LEGAJO` INT(11) NULL ,
`TBCSV002_FECHACPBTE` DATE NOT NULL ,
`TBCSV002_CUOTA` DECIMAL(12,2) NOT NULL ,
`TBCSV002_EMPRESA` CHAR(30) NOT NULL ,
`TBCSV002_DESCRIPCION` CHAR(30) NULL ,
`TBCSV002_ORDEN` INT(7) NULL ,
PRIMARY KEY (`TBCSV002_CLIENTE`) )
ENGINE = InnoDB;
SHOW WARNINGS;
CREATE UNIQUE INDEX `TBTC001_CLIENTE_UNIQUE` ON `TBCSV002` (`TBCSV002_CLIENTE` ASC) ;
SHOW WARNINGS;
LOAD DATA LOCAL INFILE ‘C:\\mebsanDB\\TBCSV002.csv’ INTO TABLE TBCSV002
FIELDS TERMINATED BY ‘;’
IGNORE 1 LINES;
SHOW WARNINGS;
LOAD DATA LOCAL INFILE ‘C:\\PRUEBODB\\TBCSV002.csv’ INTO TABLE TBCSV002
FIELDS TERMINATED BY ‘;’
LINES TERMINATED BY ‘\r\n’
IGNORE 1 LINES;
select * from TBCSV002;
La tabla la carga parcialmente y con error produjendose en cada fila desafsajes y errores.