【问题标题】:Correct LINES TERMINATED BY when importing uploaded CSV into MySQL table from PHP将上传的 CSV 从 PHP 导入 MySQL 表时纠正 LINES TERMINATED BY
【发布时间】:2014-02-13 12:33:10
【问题描述】:

我无法确定我的 CSV 行是如何终止的。我正在使用以下 PHP 代码将数据从 CSV 加载到我的数据库中。

mysql_query('LOAD DATA LOCAL INFILE "temp/test.csv"
             INTO TABLE test
             FIELDS TERMINATED BY ","
             LINES TERMINATED BY "///"
             IGNORE 1 LINES (one, two, three, four, five)');

现在,当我使用LINES TERMINATED BY "///" 时,数据已正确放入我的数据库中,除了每行的第一列是“返回”,然后是单元格数据。这不是我想要的,我想要回归消失。

我认为CSV中最后一列单元格///、return 和第一列单元格的顺序由/// 拆分,应该由/// + return 拆分。我应该更改LINES TERMINATED BY。我试过\n\r\r\n\n\r。过了一会儿,我尝试了<br> 并知道我需要帮助。

我在 Mac 上使用 MS Office 并将我的 CSV 保存为 Comma Separated Values (.csv) (sample)。我还尝试了提到的LINES TERMINATED BYMS-DOS Comma SeparatedWindows Comma Separated 文件。

运行我的查询后SELECT HEX(one) FROM test 的结果:

Array
(
    [0] => 0D6131
)
Array
(
    [0] => 0D6132
)
Array
(
    [0] => 0D6133
)

【问题讨论】:

  • 0D 是回车符 (\r)。 (而61A3039 是数字0-9。)当我将您的查询与LINES TERMINATED BY "///\r" 一起使用时,它会在我的MySQL 5.1.49 上导入CSV .

标签: php mysql sql csv load-data-infile


【解决方案1】:

正确查询

您的 CSV 包含由三个斜杠和回车分隔的行。只需在您的查询中使用LINES TERMINATED BY "///\r",它应该可以工作。至少它适用于我的 MySQL 5.1.49。

LOAD DATA LOCAL INFILE "temp/test.csv"
INTO TABLE test
FIELDS TERMINATED BY ","
LINES TERMINATED BY "///\r"
IGNORE 1 LINES (one, two, three, four, five)

调试不可打印字符

当您对不可打印的字符有疑问时,您可以随时查看 hexdump 并手动解码这些字符。通常这些字符是 ASCII。在 *NIX 上,请参阅 man ascii,否则请在 Internet 上查找表格(例如 http://man-ascii.com/)。

在MySQL中,通过HEX()函数应用获取字符串的hexdump,例如

SELECT HEX(one) FROM test

在 POSIX shell 中,使用 hexdump 生成

od -t x1 temp/test.csv

如果您不想成为那个铁杆,对于常见的空格,将其转换为 C 转义序列(例如,\r 用于回车)就足够了

od -c temp/test.csv

也许更简单(但通常更难解释)识别 EOL 类型的方法只是使用您选择的文本编辑器并让它告诉您。 CSV 是纯文本格式(与二进制格式相反)。例如。在 Vim 中打开文件并运行 se ff?。这会告诉你fileformat=<EOL-type><EOL-type> 在哪里

  • unix\n
  • dos\r\n
  • mac\r

注意多个转义级别

请注意,在我回答的开头,我只写了查询,而不是 PHP 命令来执行它。在 SQL 中,有些字符是特殊的,需要转义才能按字面意思理解(字符串内的引号),而另一些则通过转义获得特殊含义(\n 中的n)。在 PHP 中,SQL 查询必须放在字符串中,其中会发生另一级别的转义(并且针对不同的字符!)。另一个级别的逃避来自例如当您从 shell 调用 PHP 为 php -r '…'.

如果您想确保转义正确,请在将查询发送到数据库之前打印查询。

$query = '…';
print $query;
#$result = mysql_query($query);

mysql API 在 PHP 5.5 中被弃用,在 PHP 7.0 中被移除

旧的mysql API(mysql_* 函数)是deprecated in PHP 5.5removed in PHP 7.0,在以后的版本中将不可用。请参阅choice of MySQL API 的 PHP 手册。另见其他relevantanswers

【讨论】:

    【解决方案2】:

    从 CSV 文件中删除出现的 ///

    确保您的 CSV 文件以 ASCII(而非 BINARY)FTP 格式上传。

    然后查询:

    mysql_query("LOAD DATA LOCAL INFILE 'temp/test.csv' 
                 INTO TABLE test 
                 FIELDS TERMINATED BY ',' 
                 LINES TERMINATED BY '\\n' 
                 IGNORE 1 LINES (one, two, three, four, five)");
    

    【讨论】:

    • 我按照你说的做了,从 CSV 中删除了所有带有 /// 的单元格,将传输模式切换为 ASCII,上传了 CSV,用你的替换了我的查询(复制/粘贴)。不会以这种方式导入任何行。
    • 我在几分钟前更新了我的答案,你确定你在n (LINES TERMINATED BY '\\n') 之前使用了两个斜杠的更新
    • Drat,好吧,对不起! :)
    猜你喜欢
    • 2017-12-13
    • 2020-07-15
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    相关资源
    最近更新 更多