【问题标题】:Importing CSV into MySQL with PHP script使用 PHP 脚本将 CSV 导入 MySQL
【发布时间】:2019-07-02 12:44:55
【问题描述】:

我需要编写一个 PHP 脚本,它包含 166 列(是的,166 列)和大约 20.000 行的 CSV 文件。我对 csv 文件没有任何决定。最重要的是,它们不是常规的 csv 文件。由于某种原因,这些文件中的分隔符是“;”而不是冒号。有些字段是完全空的,在 csv 中表示如下:value1;;value3。

我已经有了包含匹配列的数据库和表,但还有一个额外的 id 列作为第一列。

我的尝试:

让 LOAD DATA (LOCAL) INFILE 查询正常工作,但经过 15 小时的不懈尝试,我决定在这里提问。我正在使用的生产服务器是 UBUNTU 服务器中的常规 LAMP 堆栈,但也安装了本地 XAMPP,它根本无法工作。

我也尝试将 csv 加载到一个数组中,然后循环遍历它,但 csv 从未正确修剪过。

即使 LOAD DATA INFILE 可以工作,我仍然会遇到数据库中的 1 列设置为 auto_increment 的问题,我真的不想在 sql 查询中指定 166 个列标题。

MySQL:

LOAD DATA INFILE 'D:/User Directories/Desktop/test.csv'
     INTO TABLE nwcatalogue
     FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"'
     LINES TERMINATED BY '\r\n'

PHP:

//I don't know ho to specify the delimiter for str_getcsv when used as 
//callback

$csv = array_map('str_getcsv', file('data.csv'));

LOAD DATA INFILE 有时运行没有错误,但没有插入记录。有时我会收到权限被拒绝错误,最常见的是我会收到“重复键”或“超出范围”错误。该查询既不适用于 Windows,也不适用于 linux 文件系统。

PHP str_getcsv 函数(有点)工作得更好,但有时这些值没有在正确的位置分开。 例如,我像这样在数组中获取值:

Array =>
[0] => 0;1;;;2;1;2;1
[1] => 0;4;;12;1;0;5
[2] => 5;1;1;;;1;2;;
[3] => 4;1;;;2;1;2;7

如果两个分号之间没有值,则应该插入 NULL 作为值。

简而言之,我要么需要一个数组,其中每个值都有一个特定的键,以便我可以轻松地逐行循环遍历它,要么我需要让这个 LOAD DATA INFILE 查询正常工作。

我还拥有 web 服务器和 mysql 服务器的管理员权限。

【问题讨论】:

  • 从这里stackoverflow.com/a/29984411/6701413,您可以使用匿名函数来处理它,以指定str_getcsv 的分隔符,该分隔符将分隔符作为函数str_getcsv ( string $input [, string $delimiter = "," ... 的第二个参数。同样对于NULL 值,您可以尝试每行插入数据行并指定您实际拥有的列(默认情况下会将值设置为空),或者如果可以的话,您可以在查询中硬编码NULL跨度>

标签: php mysql csv


【解决方案1】:

试试这个:

<?php
        $query = <<<eof
            LOAD DATA INFILE 'D:/User Directories/Desktop/test.csv'
             INTO TABLE nwcatalogue
             FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"'
             LINES TERMINATED BY '\n'
            (fields_go_here)
        eof;

        $db->query($query);
        ?>

对于 CSV,试试这样的:

function process_csv($file) {
   $file = fopen($file, "r");
   $data = array();
   while (!feof($file)) {
      $data[] = fgetcsv($file,null,';');
   }
   fclose($file);
   return $data;
}

然后只需调用 process_csv('D:/User Directories/Desktop/test.csv')

【讨论】:

  • 感谢朋友的回复。我也找到了第一个 sn-p,但我想避免在查询末尾放置 166 列 ^^ 至于第二个 sn-p,它不适用于我的 csv 文件。不能告诉你为什么。再次感谢。
  • @SteveGelhausen 你不能复制粘贴所有的列吗? (如果您使用的是 PHPMyAdmin,您绝对可以
  • 那是真的^^我会尽快尝试。只是我不喜欢在我的代码中看到160个指定的列。我觉得有点不专业^^
  • @Frankich 它在将列复制粘贴到查询中时起作用。谢谢^^
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 1970-01-01
  • 2014-01-02
相关资源
最近更新 更多