我正在使用一个数据库,该数据库在 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 作为文件路径,但没有成功。
请指教。谢谢你。
AFAIK,无法使用
LOAD DATA INFILE
直接从存储在 blob 中的 CSV 文件加载数据。
引述来自 MySQL 文档LOAD DATA 语句以非常高的速度将行 from a text file
读入表中。
假设有一张桌子
my_blobs
,例如:
blob_数据 | |
---|---|
“列头 1”,“列头 2”,“列头 3” | “行 2 col1”,“行 2 col2”,“行 2 col3" ... |
... | |
... |
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 中的数据具有标题行,则标题将被导入多次,但可以在导入后删除。
一种更复杂(但灵活)的方法是使用
转储列的内容,然后使用
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
可以出现在不同的职位:之前
位置,并且是首选位置。从 MySQL 8.0.20 开始,锁定子句之前的位置已被弃用;预计 MySQL 的未来版本将删除对其的支持。换句话说,在- 在尾随锁定子句之前。示例:
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
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'