提问人:dickey 提问时间:9/20/2023 最后编辑:Mark Rotteveeldickey 更新时间:9/29/2023 访问量:166
mysql 使用存储在 blob 字段中的 CSV 文件,并加载数据 infile
Mysql Using CSV Files Stored In Blob Field With Load Data Infile
问:
我正在使用一个数据库,该数据库在 blob 字段中存储了一系列 csv 文件。
我想使用带有 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 作为文件路径,但没有成功。
请指教。谢谢。
答:
AFAIK,无法直接从存储在 blob 中的 CSV 文件加载数据。LOAD DATA INFILE
引用MySQL文档中的一句话:
LOAD DATA 语句以非常高的速度将行读入表中。
from a text file
假设一个表格,如下所示:my_blobs
编号 | blob_data |
---|---|
1 | “列头 1”,“列头 2”,“列头 3”“行 1 列 1”,“行 1 列 2”,“行 1 列 3”,“行 2 列 1”,“行 2 列 2”,“行 2 列 3” ...... |
2 | ... |
3 | ... |
一种简单的方法是将表中的所有 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文档):
给定的语句最多可以包含一个子句,尽管如语法描述所示(参见第 13.2.13 节 “SELECT 语句”),可以出现在不同的位置:
SELECT
INTO
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 开始支持语句末尾的位置,并且是首选位置。从 MySQL 8.0.20 开始,锁定子句之前的位置已弃用;预计在未来的MySQL版本中将删除对它的支持。换言之,在 之后而不是在末尾产生警告。
INTO
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'
上一个:Mysql 数据加载禁用/限制
评论