【问题标题】:MySQL INTO OUTFILE override existing file?MySQL INTO OUTFILE 覆盖现有文件?
【发布时间】:2010-10-31 22:20:06
【问题描述】:

我编写了一个创建 CSV 文件的大型 sql 脚本。我想每晚调用一个 cronjob 来创建一个新的 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 给我一个错误

文件“/home/sites/example.com/www/files/backup.csv”已经存在

有没有办法让 MySQL 覆盖文件?

我可以让 PHP 检测文件是否存在并在再次创建它之前将其删除,但如果我可以直接在 MySQL 中执行它会更简洁。

【问题讨论】:

    标签: php mysql sql into-outfile


    【解决方案1】:

    不,没有办法覆盖它。来自docs

    file_name 不能是现有文件,这会防止 /etc/passwd 和数据库表等文件被破坏。

    最好每晚使用不同的文件名,因为拥有多个备份意味着您可以从存在超过一天的问题中恢复。然后,您可以维护一个始终指向最新完整 csv 的符号链接。

    【讨论】:

    • 干杯,以为我可能做不到。好吧。它不是一个备份,它更多的是用户可访问的备份。备份是单独完成的。不过,值得深思。
    • 你检查过 linux logrotate 工具吗?
    【解决方案2】:

    为什么 cron 运行的脚本中没有 rm -f /home/sites/example.com/www/files/backup.csv

    你可以在 mysql 中运行它。用\! 逃到shell 例如:

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

    【讨论】:

    • 是的,我可以做到这一点,但在 MySQL 中这样做会更整洁,因为它会遍历许多数据库并创建 100 多个文件。看起来我可能不得不用 PHP 来做。
    • 我经历了完全相同的过程,试图找到一种方法,结论是,正如文档提到的那样,为了安全,你不能这样做。
    • 我试过这个.. 但是 MySQL 的响应是:“rm: cannot remove `/tmp/my-report-2013-10.csv': Operation not allowed”.. 文件权限是 666 . 有什么想法吗?
    • 我喜欢它,为我节省了额外的 cron。
    • 执行\! whoami表明用户命令是用启动mysql客户端的用户执行的,而不是服务器。因此,该用户无法删除该文件;我们得到错误rm: cannot remove ...': Operation not allowed`
    【解决方案3】:

    对于这样的工作,我会将其放入 bash 文件中,删除该文件

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

    不过,更好的选择是实际添加时间戳。在这个时代,磁盘空间并不昂贵。

    【讨论】:

    • 不贵,只是每天更新指向新文件的 HTML 链接很尴尬。可能,是的,但可能比它需要的工作更多。谢谢。
    • 只要 lnbackup.csv 到最新和最好的版本,一旦它被制作出来 - 制作新版本,rm backup.csv,ln newversion backup.csv -- ta-da,你'完成了。
    • 是的,我喜欢 ln -s 的想法。嗯
    【解决方案4】:

    没有办法。

    您只能使用动态语句处理。

    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; 
    

    【讨论】:

      【解决方案5】:

      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") 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 "
      

      第 3 步:更新 Crontab 以每天执行脚本

      # m h dom mon dow user  command
      
       0   3  * * *   root    sh -x /home/backupCSV.sh
      

      第 4 步(可选):谢谢我;)

      【讨论】:

        【解决方案6】:

        在尝试写入文件之前,只需从 mysql 中转义到 shell 并执行 rm 命令来删除文件。例如:

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

        【讨论】:

        • 试过了,得到“rm: cannot remove ‘/tmp/blah.User.csv’: Operation not allowed”
        【解决方案7】:

        老问题.. 但是有一个选项 OVERWRITE ON 可以添加到语句中

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

        【讨论】:

        • 我已经用 MySQL 8.0 和 MariaDB 10.3 测试了OVERWRITE ON,两者都给出“ERROR 1064 (42000) ... You have an error in your SQL syntax;”。我也找不到在文档中提到OVERWRITE ON。那么,MySQL 的哪个版本/fork 支持这个选项?
        • 看起来 Amazon RDS 有 OVERWRITE ON 选项(保存到 S3 存储桶时):docs.aws.amazon.com/AmazonRDS/latest/UserGuide/…
        • 正确..对不起..我正在使用 Amazon Rds (Aurora)
        猜你喜欢
        • 2011-02-21
        • 2013-01-02
        • 2010-11-05
        • 2012-04-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-11
        • 1970-01-01
        • 2012-02-26
        相关资源
        最近更新 更多