加载 BLOB 列而不是文件

加载 BLOB 列而不是文件

有没有办法从 blob 列而不是文件加载数据

LOAD DATA FROM (SELECT A.B FROM A) INTO TABLE TEMP FIELDS
TERMINATED BY ' ' ENCLOSED BY '"' LINES TERMINATED BY '\n'

而不是加载数据文件?

答案1

对于 OP 来说已经太晚了,但将来可能会对其他人有用。

假设有如下表格my_blobs

ID blob_数据
1 “行 1 列 1” “行 1 列 2” “行 1 列 3”
“行 2 列 1” “行 2 列 2” “行 2 列 3”
...
2 ...
3 ...

简化版本是将表中的所有以空格分隔的数据导出到单个文件中,然后导入。

SELECT TRIM(TRAILING '\n' FROM blob_data) FROM my_blobs
INTO OUTFILE '/path/to/file.txt'
FIELDS ESCAPED BY '';

LOAD DATA INFILE '/path/to/file.txt'
INTO TABLE `TEMP`
FIELDS TERMINATED BY ' ' ENCLOSED BY '"'
LINES TERMINATED BY '\n';

如果您的 Blob 中的数据有标题行,那么标题将被多次导入,但可以在导入后将其删除。

一种更复杂(但更灵活)的方法是使用以下方法转储列的内容SELECT ... INTO DUMPFILE然后使用将文件读回到目标表中LOAD DATA INFILE

您可以使用如下查询来编写转储/加载脚本:

SELECT CONCAT(
    'SELECT blob_data FROM my_blobs WHERE id = ', id,' INTO DUMPFILE \'/path/to/csv_export_', id,'.csv\';\n',
    'LOAD DATA INFILE \'/path/to/csv_export_', id,'.csv\'\nINTO TABLE `TEMP`\nFIELDS TERMINATED BY \' \' ENCLOSED BY \'"\' LINES TERMINATED BY \'\\n\';\n\n'
) FROM my_blobs
INTO OUTFILE '/path/to/process_csv_files.sql'
FIELDS ESCAPED BY '' ENCLOSED BY '';

这将创建包含如下内容的文件/path/to/process_csv_files.sql

SELECT blob_data FROM my_blobs WHERE id = 1 INTO DUMPFILE '/path/to/csv_export_1.csv';
LOAD DATA INFILE '/path/to/csv_export_1.csv'
INTO TABLE `TEMP`
FIELDS TERMINATED BY ' ' ENCLOSED BY '"' LINES TERMINATED BY '\n';


SELECT blob_data FROM my_blobs WHERE id = 2 INTO DUMPFILE '/path/to/csv_export_2.csv';
LOAD DATA INFILE '/path/to/csv_export_2.csv'
INTO TABLE `TEMP`
FIELDS TERMINATED BY ' ' ENCLOSED BY '"' LINES TERMINATED BY '\n';


SELECT blob_data FROM my_blobs WHERE id = 3 INTO DUMPFILE '/path/to/csv_export_3.csv';
LOAD DATA INFILE '/path/to/csv_export_3.csv'
INTO TABLE `TEMP`
FIELDS TERMINATED BY ' ' ENCLOSED BY '"' LINES TERMINATED BY '\n';

显然,/path/to/需要对 mysqld 进程具有可读性和可写性。这可能受到secure_file_priv

笔记 (来自 MySQL 文档):

给定SELECT语句最多可以包含一个INTO子句,尽管如SELECT语法描述所示(参见第 13.2.13 节,“SELECT 语句”),INTO可以出现在不同的位置:

  • 之前FROM。例如:

    SELECT * INTO @myvar FROM t1;
    
  • 在尾随锁定子句之前。例如:

    SELECT * FROM t1 INTO @myvar FOR UPDATE;
    
  • 在 的末尾SELECT。例如:

    SELECT * FROM t1 FOR UPDATE INTO @myvar;
    

INTO从 MySQL 8.0.20 开始,支持语句末尾的位置,并且是首选位置。从 MySQL 8.0.20 开始,锁定子句之前的位置已弃用;预计在 MySQL 的未来版本中将删除对它的支持。换句话说,在INTO之后FROM但不在末尾SELECT会产生警告。

相关内容