【问题标题】:Selecting many rows of binary data from MySQL, into dumpfiles从 MySQL 中选择多行二进制数据到转储文件中
【发布时间】:2020-07-18 05:13:16
【问题描述】:

我必须从 MySQL 数据库中提取以二进制格式存储的文件。有数千个文件,因此需要动态完成。表结构如下:

__________________________________________
| Filename    |  Content                 |
------------------------------------------
| file1.pdf   | dasdsod1i9j09wej9nd...   |
| file2.pdf   | )(!)J(Jdjw19ddjw9d\00... |
| picture1.jpg| djw10dj0))!)JDFH*(#@NF...|
------------------------------------------

我知道你可以 SELECT Content INTO DUMPFILE... 但你只能在选择一行时这样做。有没有一种快速、简单的方法可以对多行​​执行此操作?

我想要的示例:SELECT Content INTO DUMPFILE Filename,所以它只需要 Content 列,并将其转储到文件中。

【问题讨论】:

  • 没有快速/“简单”的方式。你需要一个循环和 select into outfile ... 每个记录单独。

标签: mysql


【解决方案1】:

希望您对此有所了解以继续您的代码。

drop procedure if exists dump_image;
delimiter //
create procedure dump_image()
begin

declare this_id int;
declare cur1 cursor for select imageId from image;
open cur1;
  read_loop: loop
    fetch cur1 into this_id;
    set @query = concat('select blob_field from image where imageId=', 
        this_id, ' into outfile "/tmp/xyz-', this_id,'.jpg"');
    prepare write_file from @query;
    execute write_file;
  end loop;
close cur1;
end //
delimiter ;

你可以执行;

mysql> call dump_image();

See the source

【讨论】:

    【解决方案2】:

    我认为 MySQL 可以使用 UDF 来做到这一点,所以我只写了一个:

    https://github.com/spachev/mysql_udf_bundle
    

    出于安全原因,我将其限制为转储到您可以更改的 /tmp - write_to_file.cc 中的 OUTPUT_DIR 变量。要使用,请按照构建/安装说明进行操作,然后:

    SELECT write_to_file(Filename,Content) FROM tbl;
    

    还请注意,它不检查 FILE 权限,因此如果您将其部署在重要的地方,请确保将 OUTPUT_DIR 设置为任何用户可以转储随机数据的地方。它有一个安全预防措施,以确保文件名中没有/

    【讨论】:

      【解决方案3】:

      下面的代码将所有附件从 otrs 中的 blob 列保存到文件中。因为不可能在 outfile 过程中使用表达式。

      DELIMITER $$
      DROP PROCEDURE IF EXISTS  cursor_proc $$
       
      CREATE PROCEDURE cursor_proc()
       BEGIN
         DECLARE mail         VARCHAR(50);
         DECLARE id           VARCHAR(10);
         DECLARE file_date    VARCHAR(19);
         DECLARE file_name    VARCHAR(255);
         DECLARE exit_loop BOOLEAN;         
         DECLARE file_cursor CURSOR FOR SELECT 
              IFNULL(ticket.customer_user_id, 'other') as mail,
              article_data_mime_attachment.id as id, 
              article_data_mime_attachment.create_time as file_date, 
              article_data_mime_attachment.filename as file_name
              FROM
                  article_data_mime_attachment,
                  article,
                  ticket
              WHERE
                  article_data_mime_attachment.article_id = article.id AND
                  article.ticket_id = ticket.id;
         DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;
         OPEN file_cursor;
         file_loop: LOOP
           FETCH file_cursor INTO mail, id, file_date, file_name;
           SET @queryString = (SELECT CONCAT('select content from article_data_mime_attachment where id = ', id ,' into outfile "/var/lib/mysql-files/', mail, '-', id, '-', file_date, '-', file_name, '";'));
           SELECT @queryString;
           PREPARE  stmt FROM @queryString;
           EXECUTE  stmt;
           DEALLOCATE PREPARE stmt; 
           
           IF exit_loop THEN
               CLOSE file_cursor;
               LEAVE file_loop;
           END IF;
         END LOOP file_loop;
       END $$
       
       DELIMITER ;
       
       CALL cursor_proc();
      

      【讨论】:

        猜你喜欢
        • 2010-11-09
        • 1970-01-01
        • 2018-12-24
        • 2022-06-22
        • 2012-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多