PDO Prepared Inserts multiple rows in single query

后端 未结 22 1949
感情败类
感情败类 2020-11-21 23:38

I am currently using this type of SQL on MySQL to insert multiple rows of values in one single query:

INSERT INTO `tbl` (`key1`,`key2`) VALUES (\'r1v1\',\'r1         


        
相关标签:
22条回答
  • 2020-11-22 00:04

    This worked for me

    $sql = 'INSERT INTO table(pk_pk1,pk_pk2,date,pk_3) VALUES '; 
    $qPart = array_fill(0, count($array), "(?, ?,UTC_TIMESTAMP(),?)");
    $sql .= implode(",", $qPart);
    $stmt =    DB::prepare('base', $sql);
    $i = 1;
    foreach ($array as $value) { 
      $stmt->bindValue($i++, $value);
      $stmt->bindValue($i++, $pk_pk1);
      $stmt->bindValue($i++, $pk_pk2); 
      $stmt->bindValue($i++, $pk_pk3); 
    } 
    $stmt->execute();
    
    0 讨论(0)
  • 2020-11-22 00:05

    The Accepted Answer by Herbert Balagtas works well when the $data array is small. With larger $data arrays the array_merge function becomes prohibitively slow. My test file to create the $data array has 28 cols and is about 80,000 lines. The final script took 41s to complete.

    Using array_push() to create $insert_values instead of array_merge() resulted in a 100X speed up with execution time of 0.41s.

    The problematic array_merge():

    $insert_values = array();
    
    foreach($data as $d){
     $question_marks[] = '('  . placeholders('?', sizeof($d)) . ')';
     $insert_values = array_merge($insert_values, array_values($d));
    }
    

    To eliminate the need for array_merge(), you can build the following two arrays instead:

    //Note that these fields are empty, but the field count should match the fields in $datafields.
    $data[] = array('','','','',... n ); 
    
    //getting rid of array_merge()
    array_push($insert_values, $value1, $value2, $value3 ... n ); 
    

    These arrays can then be used as follows:

    function placeholders($text, $count=0, $separator=","){
        $result = array();
        if($count > 0){
            for($x=0; $x<$count; $x++){
                $result[] = $text;
            }
        }
    
        return implode($separator, $result);
    }
    
    $pdo->beginTransaction();
    
    foreach($data as $d){
     $question_marks[] = '('  . placeholders('?', sizeof($d)) . ')';
    }
    
    $sql = "INSERT INTO table (" . implode(",", array_keys($datafield) ) . ") VALUES " . implode(',', $question_marks);
    
    $stmt = $pdo->prepare ($sql);
    try {
        $stmt->execute($insert_values);
    } catch (PDOException $e){
        echo $e->getMessage();
    }
    $pdo->commit();
    
    0 讨论(0)
  • 2020-11-22 00:07

    Here is my simple approach.

        $values = array();
        foreach($workouts_id as $value){
          $_value = "(".$value.",".$plan_id.")";
          array_push($values,$_value);
        }
        $values_ = implode(",",$values);
    
        $sql = "INSERT INTO plan_days(id,name) VALUES" . $values_."";
        $stmt = $this->conn->prepare($sql);
        $stmt->execute();
    
    0 讨论(0)
  • 2020-11-22 00:09

    Two possible approaches:

    $stmt = $pdo->prepare('INSERT INTO foo VALUES(:v1_1, :v1_2, :v1_3),
        (:v2_1, :v2_2, :v2_3),
        (:v2_1, :v2_2, :v2_3)');
    $stmt->bindValue(':v1_1', $data[0][0]);
    $stmt->bindValue(':v1_2', $data[0][1]);
    $stmt->bindValue(':v1_3', $data[0][2]);
    // etc...
    $stmt->execute();
    

    Or:

    $stmt = $pdo->prepare('INSERT INTO foo VALUES(:a, :b, :c)');
    foreach($data as $item)
    {
        $stmt->bindValue(':a', $item[0]);
        $stmt->bindValue(':b', $item[1]);
        $stmt->bindValue(':c', $item[2]);
        $stmt->execute();
    }
    

    If the data for all the rows are in a single array, I would use the second solution.

    0 讨论(0)
提交回复
热议问题