使用PHP脚本将CSV导入MySQL

3
我需要编写一个PHP脚本,用于处理拥有166列(是的,166)和大约20,000行的CSV文件。我对CSV文件没有决定权。除此之外,它们不是普通的CSV文件。由于某种原因,这些文件中的分隔符是“;”而不是冒号。一些字段完全为空,在CSV中表示为这样:value1;;value3。
我已经有了带有匹配列的数据库和表格,但是第一列是附加的id列。
我尝试过以下方法: 尝试让LOAD DATA (LOCAL) INFILE查询工作,但经过15个小时的不懈尝试后,我决定在这里寻求帮助。我正在使用常规的LAMP堆栈的UBUNTU服务器上进行生产,但即使是在本地XAMPP安装中也完全无法工作。 我还尝试将CSV加载到数组中,然后循环遍历它,但CSV从来没有正确地被修剪过。 即使是LOAD DATA INFILE可以正常工作,我仍然会遇到一个问题,那就是在DB中的第一列设置为自动递增,我真的不想在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 服务器上拥有管理员权限。

从这里 https://dev59.com/sGoy5IYBdhLWcg3wJKvR#29984411,您可以使用匿名函数来指定分隔符到您的 str_getcsv,其中分隔符是函数 str_getcsv ( string $input [, string $delimiter = "," ... 的第二个参数。对于 NULL 值,您可以尝试逐行插入数据并指定实际拥有的列(这将默认设置为 null 值),或者如果可以,您可以在查询中硬编码 NULL - Frankich
1个回答

3

试试这个:

<?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') 即可。


谢谢你的回复,伙计。我也找到了第一个片段,但我想避免在查询末尾放置166列^^至于第二个片段,它不能与我的CSV文件一起使用。虽然我不知道原因。再次感谢。 - Steve Gelhausen
1
@SteveGelhausen 你不能直接复制粘贴所有的列吗?(如果你使用的是PHPMyAdmin,那么肯定可以)。 - Frankich
没错,我会尽快试一下。只是我不喜欢在我的代码中看到160个指定的列,我觉得这有点不专业。^^ - Steve Gelhausen
@Frankich 当将列复制粘贴到查询中时,它可以正常工作。谢谢 ^^ - Steve Gelhausen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接