【问题标题】:PHP for loop Insert SQLPHP for 循环插入 SQL
【发布时间】:2018-06-05 16:05:30
【问题描述】:

你能解释一下为什么这段代码没有插入数据库吗?

    //INSERT VALUES IN ORDERS
    $sqlInsert = "";
        for($i = 0; $i < count($_SESSION['cart']); $i++)
        {
            $resSelect = mysqli_fetch_assoc($sqlContent);

            $prodID = $resSelect['ProdID'];
            $price = $resSelect['Price'];
            $quantity = $_SESSION['cart'][$resSelect['ProdID']];
            $sum = ($_SESSION['cart'][$resSelect['ProdID']] * 
            $resSelect['Price']);
            $sqlInsert .= "INSERT into Order (ProdID, 
            Quantity, Price,  Sum, OrderID) 
            VALUES ($prodID, $quantity, $price, $sum, $userID);";

        }
        mysqli_query($dbLink, $sqlInsert);

这是var_dump($sqlInsert)的输出:

       INSERT INTO Order (ProdID, quantity, 
       Price, Sum, OrderID) VALUES (1, 4, 200, 800, 10);
       INSERT INTO Order (ProdID, quantity, 
       Price, Sum, OrderID) VALUES (7, 3, 200, 600, 10);
       INSERT INTO Order (ProdID, quantity, 
       Price, Sum, OrderID) VALUES (9, 3, 200, 600, 10);

这在数据库中有效。 var_dump(mysqli_query($dbLink, $sqlInsert)) 的输出总是错误的。

非常感谢提前

【问题讨论】:

  • 您应该在插入后检查mysqli errors 以获取更多信息。您使用的是数字,因此引用不是什么大问题,但您可能希望使用 prepared statementsbind_param 以避免 SQL 注入问题和任何可能的未来引用问题。
  • 另外,ORDER 是 MySQL 中的关键字,必须用反引号括起来:dev.mysql.com/doc/refman/5.7/en/keywords.html
  • mysqli_query 将只执行一个查询,但您传递给它多个查询。你应该使用 (mysqli_multi_query())[w3schools.com/php/func_mysqli_multi_query.asp]
  • 感谢它与 mysqli_multi_query() 一起使用
  • 不要使用mysqli_multi_query。它不支持占位符值,这使得它非常危险

标签: php mysql sql loops sql-insert


【解决方案1】:

正如上面提到的其他 cmets,您应该始终检查 mysqli_query() 返回的错误。见示例代码:http://php.net/manual/en/mysqli.error.php

mysqli_query() 函数不支持执行多条语句。

我确实建议使用mysqli_multi_query()。使用它几乎没有好处,而且它引入了新的潜在 SQL 注入漏洞(如著名的Little Bobby Tables cartoon)。我与 MySQL 的前工程总监进行了交谈,他说(释义):“没有理由存在多查询,它只会造成伤害。”

您应该一次执行一个 INSERT 语句。没有理由将多个语句附加在一起。

如果您担心多条语句的性能开销,可以将多行附加到单个 INSERT 语句。或者,您可以将一系列单独的 INSERT 语句包装在一个事务中。

您可能想阅读我的演示文稿Load Data Fast!,我在其中比较了插入多行数据的各种策略的性能。

【讨论】:

    【解决方案2】:

    这正是准备好的语句的用途:

    // Note that ORDER is a MySQL reserved keyword and needs special escaping
    $stmt = $dbLink->prepare("INSERT into `Order` (ProdID, 
            Quantity, Price, Sum, OrderID) VALUES (?,?,?,?,?)");
    $stmt->bind_param('iiddi', $ProdID, $Quantity, $Price, $Sum, $OrderID);
    
    for($i = 0; $i < count($_SESSION['cart']); $i++)
    {
        $resSelect = $sqlContent->fetch_assoc();
    
        $ProdID = $resSelect['ProdID'];
        $Quantity = $_SESSION['cart'][$resSelect['ProdID']];
        $Price = $resSelect['Price'];
        $Sum = $_SESSION['cart'][$resSelect['ProdID']] * $resSelect['Price'];
        $OrderID =  $userID;
    
        $stmt->execute();
    }
    

    原始代码中的错误数量多得惊人,这将使其无法正常工作,因此您今后需要更加小心,更有条理地寻找解决方案。循序渐进地构建,边做边测试,以确保您不会深入了解您不完全理解的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多