2009-06-06 14 views
44

He escrito una gran secuencia de comandos sql que crea un archivo CSV. Quiero llamar a un cronjob todas las noches para crear un nuevo archivo CSV y tenerlo disponible en el sitio web.MySQL INTO OUTFILE ¿anula el archivo existente?

decir, por ejemplo estoy guardar mi archivo en '/home/sites/example.com/www/files/backup.csv'

y mi SQL es

SELECT * INTO OUTFILE '/home/sites/example.com/www/files/backup.csv' 
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' 
    LINES TERMINATED BY '\n' 
    FROM (.... 

me da MySQL un error cuando el archivo ya existe

archivo '/home/sites/example.com/www/files/backup.csv' ya existe

¿Hay alguna manera de hacer que MySQL sobrescriba el archivo?

Podría detectar PHP si el archivo existe y eliminarlo antes de volver a crearlo, pero sería más breve si puedo hacerlo directamente en MySQL.

Respuesta

47

No, no hay manera de sobreescribirlo. Desde el docs: nombre_archivo

no puede ser un archivo existente, que entre otras cosas evita que los archivos como/etc/passwd y tablas de la base de ser destruido.

Puede ser una mejor idea usar un nombre de archivo diferente cada noche, ya que tener varias copias de seguridad significa que puede recuperarse de problemas que han existido durante más de un día. Luego puede mantener un enlace simbólico que siempre apunte a la última csv completa.

+0

vítores, pensé que no podría. agh bien No es una copia de seguridad, es más una copia de seguridad accesible por el usuario. Las copias de seguridad se realizan por separado. Aún así, comida para el pensamiento. –

+0

¿Has comprobado la herramienta linux * logrotate *? – Konerak

7

¿Por qué no rm -f /home/sites/example.com/www/files/backup.csv en el script ejecutado por cron?

Puede ejecutar esto desde dentro de mysql. Sólo escapan a la cáscara con \! Por ejemplo:

Mysql> \! rm -f /home/sites/example.com/www/files/backup.csv

+0

Sí, puedo hacerlo pero sería mejor hacerlo en MySQL porque recorre muchas bases de datos y crea cientos de archivos. Parece que debo hacerlo en PHP. –

+1

Pasé por este mismo proceso de intentar encontrar una forma y la conclusión fue que no se puede, como lo mencionan los documentos, por seguridad. –

+1

He intentado esto ... pero la respuesta de MySQL fue: "rm: no puedo eliminar' /tmp/my-report-2013-10.csv ': Operación no permitida ".. los permisos de archivos son 666. ¿Alguna idea? – lucasvscn

3

Para un trabajo como este yo colocaría en un archivo de golpe, elimine el archivo

#!/bin/bash 
rm /path/to/backup.csv 
./backup_sql_query.sh <<-- This contains the script to backup to CSV. 

La mejor opción es añadir una marca de tiempo en realidad sin embargo. El espacio en disco no es costoso en este día y edad.

+0

no es caro, simplemente incómodo para actualizar el enlace HTML al nuevo archivo todos los días. Posible, sí, pero probablemente más trabajo de lo que necesita. Gracias. –

+0

simplemente 'ln' the' backup.csv' a la versión más nueva y más grande tan pronto como se haya realizado - make new version, rm backup.csv, ln newversion backup.csv - ta-da, listo. –

+0

sí me gusta la idea ln. hmm –

2

No hay manera.

Solo es posible un procedimiento con declaración dinámica.

CREATE PROCEDURE export_dynamic(IN file_name char(64)) 
BEGIN 
set @myvar = concat('SELECT * INTO OUTFILE ',"'",file_name,"'",' FROM Table1') ; 
PREPARE stmt1 FROM @myvar; 
EXECUTE stmt1; 
Deallocate prepare stmt1; 
END; 
1

Tipo de una pregunta anticuada, pero espero que esto ayude a alguien.

Simplemente escape a un shell desde mysql y ejecute un comando rm para eliminar el archivo antes de intentar escribirlo. Por ejemplo:

Mysql> \! rm -f /home/sites/example.com/www/files/backup.csv

¡Disfrútalo!

+1

Probé esto y obtuve "rm: no se puede eliminar '/tmp/blah.User.csv': operación no permitida" –

1

3 pasos para hacer esto bien. La copia de seguridad se ejecutará todas las noches mientras duerme (o no)

PASO 1: Crear un procedimiento almacenado para su SQL

CREATE PROCEDURE backupCSV() 
SELECT * INTO OUTFILE '/home/sites/example.com/www/files/backup.csv' 
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' 
LINES TERMINATED BY '\n' 
FROM (.... 

PASO 2: Crear una secuencia de comandos "/home/backupCSV.sh" eliminar el archivo antiguo y llamar al procedimiento almacenado

echo "$(date +"%Y-%m-%d %T") START MAINTENANCE SCRIPT " 
rm /home/sites/example.com/www/files/backup.csv 
echo "$(date +"%Y-%m-%d %T") SUCCESS >> Old file deleted" 
mysql --user=[user] --password=[password] [dataBaseName] --execute="CALL backupCSV();" 
echo "$(date +"%Y-%m-%d %T") SUCCESS >> New file created" 
echo "$(date +"%Y-%m-%d %T") END MAINTENANCE SCRIPT " 

PASO 3: actualización de crontab para ejecutar la secuencia de comandos todos los días

# m h dom mon dow user command 

0 3 * * * root sh -x /home/backupCSV.sh 

PASO 4 (opcional): gracias;)

Cuestiones relacionadas