0

MySQL INTO OUTFILE: Как переопределить существующий файл?

5

У меня есть большой SQL-скрипт, который создает CSV-файл. Я хочу настроить cron-задачу, которая будет выполняться каждую ночь, чтобы создавать свежий CSV-файл и делать его доступным на сайте.

К примеру, я сохраняю свой файл по пути '/home/sites/example.com/www/files/backup.csv'.

Мой SQL-запрос выглядит следующим образом:

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

Однако MySQL выдаёт ошибку, если файл уже существует:

File '/home/sites/example.com/www/files/backup.csv' already exists

Существует ли способ заставить MySQL перезаписывать файл?

Я мог бы использовать PHP для проверки наличия файла и его удаления перед созданием нового, но было бы удобнее, если бы я мог сделать это непосредственно в MySQL.

5 ответ(ов)

0

Вопрос: Почему не использовать rm -f /home/sites/example.com/www/files/backup.csv в скрипте, выполняемом через cron?

Ответ: Вы можете выполнить эту команду внутри MySQL, используя команду для перехода в оболочку: \!. Например:

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

Это позволяет избежать потенциальных проблем, связанных с выполнением команд оболочки напрямую в cron. В случае выполнения команд через MySQL, вы также можете сохранять логи и обрабатывать ошибки более эффективно.

0

Для такой задачи я бы поместил код в bash-скрипт и удалил файл:

#!/bin/bash
rm /path/to/backup.csv
./backup_sql_query.sh  # Здесь находится скрипт для резервного копирования в формате CSV.

Однако лучшее решение — добавить метку времени к файлу. В наши дни дисковое пространство не так уж и дорого.

0

В вашем случае действительно нет другого способа использовать динамические SQL-запросы. Но вы можете создать хранимую процедуру, которая принимает имя файла в качестве параметра и выполняет динамический запрос. Вот пример:

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; 

Эта процедура создает SQL-запрос, который выбирает все данные из Table1 и экспортирует их в указанный файл. Не забудьте, что у пользователя, выполняющего эту процедуру, должны быть достаточные права для записи в файловую систему.

0

Вот перевод на русский в стиле ответа на StackOverflow.com:

3 шага для правильного выполнения резервного копирования

Ваше резервное копирование будет выполняться каждую ночь, пока вы спите (или нет).

ШАГ 1: Создайте хранимую процедуру для вашего 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 ( ....

ШАГ 2: Создайте скрипт "/home/backupCSV.sh", чтобы удалить старый файл и вызвать хранимую процедуру

echo "$(date +"%Y-%m-%d %T") СТАРТ СКРИПТА ОБСЛУЖИВАНИЯ"
rm /home/sites/example.com/www/files/backup.csv
echo "$(date +"%Y-%m-%d %T")    УСПЕШНО >> Старый файл удалён"
mysql --user=[user] --password=[password] [dataBaseName] --execute="CALL backupCSV();"
echo "$(date +"%Y-%m-%d %T")    УСПЕШНО >> Новый файл создан"
echo "$(date +"%Y-%m-%d %T") КОНЕЦ СКРИПТА ОБСЛУЖИВАНИЯ"

ШАГ 3: Обновите Crontab для ежедневного выполнения скрипта

# m h dom mon dow user  command

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

ШАГ 4 (по желанию): поблагодарите меня 😉

Теперь ваше резервное копирование будет выполняться автоматически каждый день. Не забудьте заменить [user], [password] и [dataBaseName] своими данными.

0

Вам нужно просто перейти в оболочку из MySQL и выполнить команду rm для удаления файла перед тем, как вы попытаетесь его переписать. Например:

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

Обратите внимание, что использование команды rm может удалить файл без возможности восстановления, поэтому будьте осторожны.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь