上传 csv 并插入或更新结果失败

Posted

技术标签:

【中文标题】上传 csv 并插入或更新结果失败【英文标题】:Upload csv and insert or update the results failing 【发布时间】:2016-03-31 18:26:15 【问题描述】:

谁能看到我在这里做错了什么?基本上应该发生的是您上传csv,然后将行拉出并检查数据库是否存在该行,如果存在则更新它,如果不存在则插入它。如果该行是空白的,它会忽略它。

实际发生的情况是,当我上传 csv 文件时,无论是否在数据库中,我都会为 4 条测试线中的每一条“更新”。

另外,如果有人可以提出更好的方法,或者减少代码,请告诉我,因为我知道编码并不是想象中最棒的。

if(isset($_GET['uploadfile'])) 
    $file = fopen($_FILES['csvfile']['tmp_name'], 'r+');
    while(! feof($file))
    
        $line = fgetcsv($file, 0, ',');

        list($productcode, $v9cm, $v1litre, $v2litre, $v3litre, $v5litre, $v7litre) = $line;
        $rowcheck = "SELECT * FROM `stock` WHERE `productcode` = '$productcode'";

if (@mysql_num_rows(mysql_query($rowcheck))!=1) 

    if ($productcode == NULL OR $productcode == '')
    else 
        $datecreated = date('Y-m-d');
// Insert Posted Data
mysqli_query($db,"INSERT INTO stock (`datecreated`, `productcode`, `9cm`, `1litre`, `2litre`, `3litre`, `5litre`, `7litre`) VALUES ('$datecreated', '$productcode', '$v9cm', '$v1litre', '$v2litre', '$v3litre', '$v5litre', '$v7litre')") or die ('Unable to execute query. '. mysqli_error());
    echo $productcode.' - Added<br/ >';

        

else
    if ($productcode == NULL OR $productcode == '')
    else 
$stmt = $db->prepare("UPDATE stock SET 9cm = '$v9cm',1litre = '$v1litre',2litre = '$v2litre',3litre = '$v3litre',5litre = '$v5litre',7litre = '$v7litre' WHERE productcode = '$productcode'");

if ($stmt === FALSE)  echo "an error has occured"; 

$stmt->execute(); 
$stmt->close(); 
echo $productcode.' - Updated<br/ >';
    


fclose($file);



【问题讨论】:

由于某种原因,您的查询总是返回一些东西。调试您的查询,print_r(mysql_fetch_array(mysql_query($rowcheck))) 很高兴你能成功!记得在你的答案上打勾,以便我们知道。 【参考方案1】:

似乎缺少一个大括号,我认为它确实会尝试更新任何内容 - 缩进语句以帮助使其更清晰,并添加 mysqli 而不是 mysql 似乎是错误的 - 假设一切都应该是 mysqli .希望能有所帮助。

您需要添加清理/消毒/转义代码,但我假设您知道

if(isset($_GET['uploadfile']))
    $file = fopen($_FILES['csvfile']['tmp_name'], 'r+');
        while(! feof($file))
        $line = fgetcsv($file, 0, ',');


        list($productcode, $v9cm, $v1litre, $v2litre, $v3litre, $v5litre, $v7litre) = $line;

        $rowcheck = "SELECT * FROM `stock` WHERE `productcode` = '$productcode'";

             if (@mysqli_num_rows(mysqli_query($rowcheck))!=1)

                 if ($productcode == NULL OR $productcode == '')
                 echo "Product code missing and rowcheck is not 1<br/ >";  // for testing
                 else
                 $datecreated = date('Y-m-d');
                 // Insert Posted Data
                 mysqli_query($db,"INSERT INTO stock (`datecreated`, `productcode`, `9cm`, `1litre`, `2litre`, `3litre`, `5litre`, `7litre`) VALUES ('$datecreated', '$productcode', '$v9cm', '$v1litre', '$v2litre', '$v3litre', '$v5litre', '$v7litre')") or die ('Unable to execute query. '. mysqli_error());
                 echo $productcode.' - Added<br/ >';
                     

             elseif($productcode == NULL OR $productcode == '')
             echo "Product code missing<br/ >"; // for testing
             else
             $stmt = $db->prepare("UPDATE stock SET 9cm = '$v9cm',1litre = '$v1litre',2litre = '$v2litre',3litre = '$v3litre',5litre = '$v5litre',7litre = '$v7litre' WHERE productcode = '$productcode'");

                  if ($stmt === FALSE)
                  echo "an error has occured<br/ >"; 
                  else
                  $stmt->execute(); 
                  $stmt->close(); 
                  echo $productcode.' - Updated<br/ >';
                  
             
       
 

您可能还想了解直接通过临时名称http://www.acunetix.com/websitesecurity/php-security-4/ 使用上传文件的安全隐患。

【讨论】:

谢谢,我现在每次都被“添加”,即使该条目仍然存在,所以我现在在数据库中使用相同的产品代码获得了许多,但这不应该发生,因为它应该检查该产品代码是否存在。 顺便说一句,这部分代码只是为了检查 csv 文件中的空行,因为我不确定如何正确处理它,所以它所做的只是检查是否有是一个产品代码就行了。 $productcode == NULL 或 $productcode == '') 我不确定它是否真的逐行执行,因为似乎第一个结果是真还是假,那么所有结果都是真还是假。【参考方案2】:

这最终奏效了:

    if(isset($_GET['uploadfile']))
        $file = fopen($_FILES['csvfile']['tmp_name'], 'r+');
            while(! feof($file))
            $line = fgetcsv($file, 0, ',');


            list($productcode, $v9cm, $v1litre, $v2litre, $v3litre, $v5litre, $v7litre) = $line;


            $query = mysqli_query($db, "SELECT * FROM stock WHERE productcode='".$productcode."'");

    if(mysqli_num_rows($query) > 0)

         $stmt = $db->prepare("UPDATE stock SET 9cm = '$v9cm',1litre = '$v1litre',2litre = '$v2litre',3litre = '$v3litre',5litre = '$v5litre',7litre = '$v7litre'
           WHERE productcode = '$productcode'");

        if ($stmt === FALSE)  echo "an error has occured"; 

        $stmt->execute(); 
        $stmt->close(); 
        echo $productcode.' - Updated<br/ >';

    else
        // do something
        if (!mysqli_query($db,$query))
        

              $datecreated = date('Y-m-d');
        // Insert Posted Data
       mysqli_query($db,"INSERT INTO stock (`image`,`genusid`,`datecreated`, `productcode`, `9cm`, `1litre`, `2litre`, `3litre`, `5litre`, `7litre`) VALUES ('None.gif','5','$datecreated', '$productcode', '$v9cm', '$v1litre', '$v2litre', '$v3litre', '$v5litre', '$v7litre')") or die ('Unable to execute query. '. mysqli_error());
            echo $productcode.' - Added<br/ >';
        
    


                    

【讨论】:

【参考方案3】:

使用 mysql 的 ON DUPLICATE KEY UPDATE 子句(http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html)可能更容易。

在此处查看 hjpotter92 的答案:On Duplicate Key Update same as insert。您的查询需要修改为以下内容:

INSERT INTO table (id,a,b,c,d,e,f,g)
    VALUES (1,2,3,4,5,6,7,8) 
    ON DUPLICATE KEY
        UPDATE a=a, b=b, c=c, d=d, e=e, f=f, g=g;

这应该允许您删除大部分条件逻辑并减少您运行的查询数量。

【讨论】:

以上是关于上传 csv 并插入或更新结果失败的主要内容,如果未能解决你的问题,请参考以下文章

需要帮助上传 csv

使用 C# 使用 CSV 文件填充 DataGridView,并使用结果更新 Access 数据库

CQL Cassandra - 如何在插入或更新中使用 SELECT 结果

Bash:使用 CSV 文件构建循环并保存结果

简单记录下Jmeter通过CSV保存测试数据,测试用例,及将测试结果导出到Excel里

Angular 4 - 上传 CSV