有没有办法从 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
会产生警告。