0

我正在尝试解决更新问题或将新产品从文件(csv)插入数据库。

问题是 CSV 文件中只有产品的编号和供应商。所以我需要为每个产品寻找这个供应商和编号的 ID。如果没有找到产品,我需要插入新的,否则我只会更新存储信息和价格。

该 csv 有 500 000 个产品 (34MB)。

现在我正在用这样的代码解决这个问题(但由于没有内存空间(使用 2GB),脚本在 50 000 个文件行后停止:

        while (!feof($file_handle)) 
    {   
        $data = fgetcsv($file_handle,5096,$i->column_separator);

        if($row >= ($i->firstrow-1) && !empty($data[$i->column_product_code-1]) && !empty($data[$i->column_product_name-1]) && !empty($data[$i->column_price-1]) && $data[$i->column_price-1] > 0)
        {                            
            @$code = str_replace(array(' ','.','-','/'),'',$data[$i->column_product_code-1]);
            @$supplier = iconv('WINDOWS-1250','UTF-8', $data[$i->column_producer_name-1]);
            @$name = iconv('WINDOWS-1250','UTF-8', $data[$i->column_product_name-1]);

            $article = $articleModel->searchImport($code,$supplier,isset($data[$i->column_producer_code-1]) ? $data[$i->column_producer_code-1]:NULL);

            if($article !== FALSE)
            {
                $importqueueModel->update()
            }
            else
            { 
                $importqueueModel->insert()
            }

我无法弄清楚如何从文件中匹配产品代码和供应商以从数据库中获取 ID,以便我可以更新或将新产品插入数据库中。

请帮助,任何提示将不胜感激。

谢谢

4

3 回答 3

3

作为一般经验法则,如果您认为需要在脚本中运行数百个查询,那么您做错了。数千?非常错误。

不要将 CSV 中的数据直接加载到已经包含实时数据的目标表中 - 将其加载到临时表中 - 然后单个 insert....select 将填充相关记录:

INSERT INTO suppliers (name, status)
SELECT c.supplier, 'new'
FROM csv_imported c
LEFT JOIN suppliers s
ON c.supplier=s.name
WHERE s.name is NULL
AND c.supplier IS NOT NULL;

并且使用 mysqlimport / load data infile 也消除了对大量代码的需要。

因为没有内存空间(使用了2GB)

即使以错误的方式进行操作也不会导致此问题 - 您的代码中存在错误。

于 2012-11-21T00:12:34.343 回答
0

您可以添加一个新方法$importQueueModel来支持 MySQL 扩展的 INSERT 语法ON DUPLICATE UPDATE。这不是便携式的,但可以解决您当前的问题。

另一个(更好的)解决方案是编写一个 MySQL 脚本来处理更新。您可以修改您的 PHP 脚本以输出 SQL,然后单独运行它。

插入参考手册。

于 2012-11-21T00:02:36.007 回答
0

在您的代码中的某处,您正在存储有关从 CSV 文件读取的每一行的数据。这似乎不包含在您发布的不完整片段中,除非它是$articleModel->searchImport()方法调用的一部分。

如果幸运的话,您在帖子中省略的错误/异常消息可能会直接指向有问题的行。

于 2012-11-20T23:57:19.983 回答