MySql LOAD DATA INFILE 以逗号失败
Posted
技术标签:
【中文标题】MySql LOAD DATA INFILE 以逗号失败【英文标题】:MySql LOAD DATA INFILE failing with commas 【发布时间】:2021-12-06 02:16:33 【问题描述】:声明如下:
LOAD DATA INFILE '/var/lib/mysql-files/test.csv'
INTO TABLE test
FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '\\'
这里有一行可以很好地导入:
1450327840667357185, 1, "This is my text"
如果文本字段有逗号,则会失败。例如,看到这一行:
1450327840667357185, 1, "This is my text, with a comma in it"
为什么会失败?
如果我转义逗号(通过在它前面放一个反斜杠)它可以正常工作。但这没有意义。我已经规定字段可以用双引号括起来,为什么不接受其中的所有内容作为字段的内容呢?
如果我必须重新处理所有文本以引用逗号,那将是一项艰巨的任务。
【问题讨论】:
您已指定FIELDS TERMINATED BY ','
- 为什么您会感到惊讶?
您的 CSV 在 ,
分隔符后有空格。我没有 MySQL 可以玩,但我希望这意味着它将这些空间视为值的一部分,从而导致各种问题。试试TERMINATED BY ', '
?
这就是问题所在。我在文本字段值中的逗号后面也看到了一个空格...这个空格在实际数据中不存在吗?
@Akina - 通过将', '
指定为分隔符/终止符(包括空格),第三个值现在被读取为以"
开头,而不是从一个空格开始。这意味着ENCLOSED BY '"'
现在按预期“工作”;解析正确地看到 quoted string 内的 ,
,因此不作为分隔符处理。相反,正如问题中所写,第三个值以空格开头,而不是 "
,因此不是带引号的字符串,导致解析器认为有四个分隔值。
@MatBailie 请将此解释添加到您的答案中 - 这很关键。
【参考方案1】:
您的 CSV 在 ,
分隔符后有空格。
我没有 MySQL 可玩,但我希望这意味着它会将这些空格视为值的一部分,从而导致各种问题。
这意味着 CSV 行被读取为...
VAL =1450327840667357185
SEP = ,
VAL = 1
SEP = ,
VAL = "This is my text
SEP = ,
VAL = with a comma in it"
请注意,值中包含前导空格。
这意味着第三个值不是以"
开头(它以空格开头),所以ENCLOSED BY '"'
没有做任何事情。这意味着解析器将字符串视为未引用,这反过来意味着后续的,
被视为分隔符。
试试TERMINATED BY ', '
...
这意味着解析器现在将该行读取为...
VAL =1450327840667357185
SEP = ,
VAL = 1
SEP = ,
VAL = "This is my text, with a comma in it"
注意第三个值现在确实以"
开头(因为前导空格现在是分隔符的一部分),并且所以是一个引用的字符串,所以后面的,
是不是 strong> 视为分隔符。
【讨论】:
【参考方案2】:使用Input Preprocessing。将整行加载到一个变量中,然后将其解析为单独的列。
LOAD DATA INFILE '/var/lib/mysql-files/test.csv'
INTO TABLE test
-- FIELDS TERMINATED BY ''
(@tmp)
SET column1 = SUBSTRING_INDEX(@tmp, ',', 1),
@tmp = TRIM(SUBSTRING(@tmp FROM 1 + LOCATE(',', @tmp))),
column2 = SUBSTRING_INDEX(@tmp, ',', 1),
column3 = TRIM(BOTH '"' FROM TRIM(SUBSTRING(@tmp FROM 1 + LOCATE(',', @tmp))))
【讨论】:
以上是关于MySql LOAD DATA INFILE 以逗号失败的主要内容,如果未能解决你的问题,请参考以下文章
MySQL:启用 LOAD DATA LOCAL INFILE
MySQL通过 LOAD DATA INFILE 批量导入数据
mysql load data local infile问题