Mysql 使用存储在 Blob 字段中的 CSV 文件并加载数据 Infile

问题描述 投票:0回答:1

我正在使用一个数据库,该数据库在 blob 字段中存储了一系列 csv 文件。

我想使用 select with where 子句选择正确的文件 (.csv),然后通过拆分每个逗号分隔的列来为 .csv 中的每一行插入记录。

通常,如果文件位于磁盘上,我会使用:

LOAD DATA INFILE 'file-path'
INTO TABLE some-table
FIELDS TERMINATED BY ','
IGNORE 1 ROWS;

或者如果从选择插入记录我会使用:

INSERT INTO target-table
SELECT * FROM source-table
WHERE condition;

我还尝试将包含文件的表上的选择结果作为变量传递到 LOAD DATA INFILE 作为文件路径,但没有成功。

请指教。谢谢你。

mysql csv blob load-data-infile
1个回答
0
投票

AFAIK,无法使用

LOAD DATA INFILE
直接从存储在 blob 中的 CSV 文件加载数据。 引述

来自 MySQL 文档

LOAD DATA 语句以非常高的速度将行
from a text file

读入表中。


假设有一张桌子
my_blobs

,例如:


id1“行 1 col1”,“行 1 col2”,“行 1 col3”23
blob_数据
“列头 1”,“列头 2”,“列头 3”“行 2 col1”,“行 2 col2”,“行 2 col3"
...

...
...
一个简单的方法是将表中的所有 CSV 数据导出到单个文件中,然后导入。仅当 blob 中的文件结构相同且不存在(可能有限的)编码差异时,此方法才有效。

SELECT TRIM(TRAILING '\n' FROM blob_data) FROM my_blobs INTO OUTFILE '/path/to/file.csv' FIELDS ESCAPED BY ''; LOAD DATA INFILE '/path/to/file.csv' INTO TABLE `some-table` FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

如果 blob 中的数据具有标题行,则标题将被导入多次,但可以在导入后删除。

一种更复杂(但灵活)的方法是使用

SELECT ... INTO DUMPFILE

 转储列的内容,然后使用 
LOAD DATA INFILE
 将文件读回目标表。这更加灵活,因为您可以根据 
LOAD DATA INFILE
表中的元数据对
my_blobs
进行更改。
您可以使用这样的查询来编写转储/加载脚本:

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 `some-table`\nFIELDS TERMINATED BY \',\' ENCLOSED BY \'"\'\nLINES TERMINATED BY \'\\n\'\nIGNORE 1 ROWS;\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 `some-table`
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;


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 `some-table`
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;


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 `some-table`
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;

注意(
来自 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;
    

    
    从 MySQL 8.0.20 开始支持语句末尾的 
  • INTO
位置,并且是首选位置。从 MySQL 8.0.20 开始,锁定子句之前的位置已被弃用;预计 MySQL 的未来版本将删除对其的支持。换句话说,在

INTO

 之后但不在 
FROM
 末尾的 
SELECT
 会产生警告。
另一句话

来自文档

文件名必须以文字字符串形式给出。在 Windows 上,将路径名称中的反斜杠指定为正斜杠或双反斜杠。

# Typical Windows path with secure_file_priv set 'C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\file.csv' # or 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/file.csv'


© www.soinside.com 2019 - 2024. All rights reserved.