web-dev-qa-db-fra.com

MySQL INTO OUTFILE écraser le fichier existant?

J'ai écrit un gros script sql qui crée un fichier CSV. Je veux appeler un cronjob tous les soirs pour créer un nouveau fichier CSV et le rendre disponible sur le site Web.

Dites par exemple que je stocke mon fichier dans '/home/sites/example.com/www/files/backup.csv'

et mon SQL est

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

MySQL me donne une erreur lorsque le fichier existe déjà

Le fichier '/home/sites/example.com/www/files/backup.csv' existe déjà

Existe-t-il un moyen de faire écraser MySQL par le fichier?

Je pourrais avoir PHP détecter si le fichier existe et le supprimer avant de le recréer mais ce serait plus succinct si je pouvais le faire directement dans MySQL.

51
Derek Organ

Non, il n'y a aucun moyen de l'écraser. De la docs :

nom_fichier ne peut pas être un fichier existant, ce qui empêche notamment la destruction de fichiers tels que/etc/passwd et les tables de base de données.

Il peut être préférable d'utiliser un nom de fichier différent chaque nuit, car avoir plusieurs sauvegardes signifie que vous pouvez récupérer des problèmes qui existent depuis plus d'une journée. Vous pouvez alors maintenir un lien symbolique qui pointe toujours vers le dernier csv complet.

54
brian-brazil

Pourquoi pas rm -f /home/sites/example.com/www/files/backup.csv dans le script exécuté par cron?

Vous pouvez l'exécuter depuis mysql. Échappez-vous simplement au Shell avec \! Par exemple:

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

8
Flavius Stef

Pour un travail comme celui-ci, je le placerais dans un fichier bash, supprimez le fichier

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

La meilleure option consiste à ajouter un horodatage. L'espace disque n'est pas cher de nos jours.

3
user118659

Il n'y a pas moyen.

Un seul possible, vous pouvez procéder avec instruction dynamique.

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; 
3
mani

3 étapes pour le faire correctement. Votre sauvegarde sera exécutée chaque nuit pendant que vous dormez (ou non)

ÉTAPE 1: créer une procédure stockée pour votre 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 ( ....

ÉTAPE 2: Créez un script "/home/backupCSV.sh" pour supprimer l'ancien fichier et appeler la procédure stockée

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 "

ÉTAPE 3: Mettez à jour Crontab pour exécuter le script tous les jours

# m h dom mon dow user  command

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

ÉTAPE 4 (optionnel): merci moi;)

2
Benjamin SAVIGNAC

vieille question .. mais il y a une option OVERWRITE ON que vous pouvez ajouter à la déclaration

SELECT * INTO OUTFILE '/home/sites/example.com/www/files/backup.csv'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n' OVERWRITE ON
...
0
da Bich

Échappez simplement à un shell depuis mysql et exécutez une commande rm pour supprimer le fichier avant d'essayer de l'écrire. Par exemple:

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