防止LOAD DATA INFILE转义双引号

时间:2016-02-13 14:03:06

标签: mysql csv escaping load-data-infile

我有以下csv数据:

"E12 98003";1085894;"HELLA";"8GS007949261";"";1
"5 3/4"";652493;"HELLA";"9HD140976001";"";1

某些字段包含在双引号中。问题是 正如您在第二行中看到的那样,第一列中的数据在末尾包含一个双引号作为数据的一部分。

我尝试了以下几点:

LOAD DATA INFILE file.csv
INTO TABLE mytable
FIELDS TERMINATED BY ';' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'

但它会使用数据中的引号来转义括号引号的字段。我还尝试ESCAPED BY ''ESCAPED BY '\\'但没有成功。 有没有办法阻止LOAD DATA INFILE命令转义双引号? 或者我应该解析csv并在只有一个时加上双引号? 我正在解析文件,无论如何使用powershell将编码更改为utf8。有没有办法快速解决这个问题?我的powershell代码:

function Convert-FileToUTF8 {

    param([string]$infile,
          [string]$outfile,
          [System.Int32]$encodingCode)

    $encoding = [System.Text.Encoding]::GetEncoding($encodingCode)
    $text = [System.IO.File]::ReadAllText($infile, $encoding)
    [System.IO.File]::WriteAllText($outfile, $text)

}

好的,我使用.NET正则表达式来修复csv。这是昂贵的,但不是太多。 我写了

$text = [regex]::Replace($text, "(?m)(?<!^)(?<!\;)""(?!\;)(?!\r?$)", '""');

在函数的最后一行之前,似乎工作正常。由于我是正则表达式的新手,因此可能会有所改进。

2 个答案:

答案 0 :(得分:2)

主要问题是输入数据构成无效的CSV语法,如RFC-4180第7段所述:

  

如果使用双引号括起字段,那么出现在字段内的双引号必须先用另一个双引号进行转义。

但是在您的PowerShell脚本中,您可以尝试使用 $ text 上的replace method修复此问题,一旦获得它的价值:

$text = $text.Replace('"";', '""";')

这应该足够了,因为如果它们出现在数据的其他地方,加载器将很好地处理未转义的双引号,如mysql.com(我的亮点)所述:

  

如果该字段以ENCLOSED BY字符开头,则该字符的实例只有在 后跟字段或行{时才会被识别为终止字段值 {1}}序列。

当然,如果格式错误的CSV包含TERMINATED BY的数据,那么您仍有问题。但很难确定这种情况是否会终止数据,或者应该被视为数据的一部分,即使对于人类也是如此: - )

mysql.com上要注意的另一件事:

  

如果输入值未必包含在引号内,请在"; BY关键字前使用OPTIONALLY

答案 1 :(得分:0)

此外:使用ENCLOSED BY选项时,在MySQL中导入用引号引起来的CSV文件效果很好。.除非所包含的字段是行中的最后一个字段,并且您使用Excel创建了CSV文件。 Excel在行的最后一个字段之后省略字段分隔符。 MySQL不会介意...除非最后一个字段用引号引起来。然后导入在该行终止。

示例:
可以正常工作:...; value2; value3(无尾随分隔符)
这也可以正常工作...;“值2”;值3(用引号引起来的值)
值2;“值3”; (最后一个字段值括在引号和结尾的分隔符中)
但这会破坏导入:...; value2;“ value 3”(最后一个字段值括在引号中,没有尾随分隔符)

花些时间弄清楚这一点;希望分享这可以节省其他人的时间。