SQL插入多行,foreach

Posted

技术标签:

【中文标题】SQL插入多行,foreach【英文标题】:SQL insert multiple rows, foreach 【发布时间】:2015-02-09 14:35:07 【问题描述】:

我正在尝试将insert 多个rows 放入我的数据库中,具体取决于返回的数组迭代次数。

插入工作正常,但插入多于 1 行,无论数组中有什么。

function createOrder()

  $CustomerID = $_SESSION['CustomerID'];
  $BasketID = $_SESSION['BasketID'];

  // create a new entry with an OrderID
  $orders = new Basket;
  $orders->storeFormValues( $_POST );
  // Collect the OrderID returned from insertOrder(); and insert into 'Orders'
  $OrderID = $orders->insertOrder($CustomerID);

  // Populate OrderDetails with items in users Basket.
  $data = Basket::getBasket($BasketID);
  $results['basket'] = $data['results'];

  // Insert the order details into the orderDetails DB.
  $orders->insertOrderDetails($OrderID, $BasketID, $CustomerID, $results); 
;

和循环:

public static function insertOrderDetails($OrderID, $BasketID, $CustomerID, $results)
   $conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );

    // for each row insert into the DB
    foreach ( $results['basket'] as $row ) 
      $sql = "INSERT INTO OrderProducts (OrderID, ProductName, Price, Quantity) 
              VALUES (:OrderID, :ProductName, :Price, :Quantity)";

      $st = $conn->prepare( $sql );
      $st->bindValue( ":OrderID", $OrderID, PDO::PARAM_INT );
      $st->bindValue( ":ProductName", $row->ProductName, PDO::PARAM_STR );
      $st->bindValue( ":Price", $row->Price, PDO::PARAM_INT );
      $st->bindValue( ":Quantity", $row->Quantity, PDO::PARAM_STR );
      $st->execute();

   
    $conn = null;

而数组,$results 看起来像;

array(1) 
  ["basket"]=>
  array(2) 
    [0]=>
    object(Basket)#3 (10) 
      ["OrderID"]=>
      NULL
      ["CustomerID"]=>
      NULL
      ["OrderItemID"]=>
      NULL
      ["ProductID"]=>
      string(1) "9"
      ["Quantity"]=>
      string(1) "4"
      ["ProductName"]=>
      string(12) "Cheese Bagel"
      ["Price"]=>
      string(1) "1"
      ["NameType"]=>
      string(5) "Bagel"
      ["BasketProductID"]=>
      string(2) "25"
      ["BasketID"]=>
      string(1) "3"
    
    [1]=>
    object(Basket)#5 (10) 
      ["OrderID"]=>
      NULL
      ["CustomerID"]=>
      NULL
      ["OrderItemID"]=>
      NULL
      ["ProductID"]=>
      string(1) "2"
      ["Quantity"]=>
      string(1) "1"
      ["ProductName"]=>
      string(15) "The British BLT"
      ["Price"]=>
      string(1) "3"
      ["NameType"]=>
      string(5) "Bagel"
      ["BasketProductID"]=>
      string(2) "26"
      ["BasketID"]=>
      string(1) "3"
    
  

非常感谢任何建议!

【问题讨论】:

你的主键和唯一键是什么? PDO 默认使用“return boolean false”来表示失败。您没有检查任何数据库代码中的故障,这意味着您只是假设没有任何事情会失败。 @Legionar,在OrderProducts 中,OrderProductID 是主要的且唯一的,Orders,OrderID 是主要的。 @MarcB 谢谢,我计划创建一些条件来检查脚本的主要部分是否正常工作。 【参考方案1】:

我在数据库中的主键没有设置为自动增量。改变这个解决了这个问题。一旦允许,将删除。感谢您的帮助

【讨论】:

是的,我给你写了评论给你的问题,你的主键和唯一键是什么? :-)【参考方案2】:

可能只是为 INSERT 查询尝试这个变体:

insert into tablename (id,blabla) values(1,'werwer'),(2,'wqewqe'),(3,'qwewe');

例如:

$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );

foreach ( $results['basket'] as $key => $row ) 
    $sql = "INSERT INTO OrderProducts (OrderID, ProductName, Price, Quantity) VALUES ";
    $sql .= "(:OrderID" . $key . ", :ProductName" . $key . ", :Price" . $key . ", :Quantity" . $key . "),";


$sql = substr($sql, 0, -1);
$st = $conn->prepare( $sql );

foreach ( $results['basket'] as $key => $row ) 
    $st->bindValue( ":OrderID" . $key, $OrderID, PDO::PARAM_INT );
    $st->bindValue( ":ProductName" . $key, $row->ProductName, PDO::PARAM_STR );
    $st->bindValue( ":Price" . $key, $row->Price, PDO::PARAM_INT );
    $st->bindValue( ":Quantity" . $key, $row->Quantity, PDO::PARAM_STR );

$st->execute();

两个 foreach 但一个插入查询到数据库。

【讨论】:

感谢 Dmitry,我不确定如何单独填充每组括号? 我没有测试过,但我认为应该可以使用这个变体(编辑了我的答案)。 感谢 Dmitry,一旦我将 AI 添加到数据库中,您的解决方案就会起作用。您介意解释一下我的脚本是否有任何好处吗?谢谢:) 当然。我认为我的变体插入速度会更快,因为对数据库的单个查询与多个查询。但是如果记录的数量很少,那么您将看不到差异。关于这个的一些问题:***.com/questions/26456219/… 很有意义,如果我有时间会更新以包含为首选方法。谢谢!【参考方案3】:

阅读http://php.net/manual/en/pdostatement.execute.php,您可能需要在执行下一条语句之前关闭游标。

注意: 笔记: 一些驱动程序需要在执行下一条语句之前关闭游标。

另一个注意事项,您可能不必在每次迭代中创建语句。

【讨论】:

呃,任何 OP 代码中的 mysqli 在哪里?它正在使用 PDO 对不起,马克,我错过了那个细节 :)

以上是关于SQL插入多行,foreach的主要内容,如果未能解决你的问题,请参考以下文章

如何将动态sql的多行结果插入另一个表?

如何在 SQL Server 中插入多行?

使用存储过程(SQL + C#)将数据插入一个表,然后将多行插入另一个表

试图在我的 SQL 表中插入多行。总是显示 SQL 命令未正确结束 [重复]

C#,将多行插入 SQL 数据库

Oracle SQL插入多行并返回一些东西