在PHP PDO MYSQL中插入多行的最佳方法是什么?

时间:2014-10-19 22:43:33

标签: php mysql pdo sql-insert

说,我们在表中插入了多行:

$rows = [(1,2,3), (4,5,6), (7,8,9) ... ] //[ array of values ];

使用PDO:

$sql = "insert into `table_name` (col1, col2, col3) values (?, ?, ?)" ;

现在,您应该如何继续插入行?喜欢这个?

$stmt = $db->prepare($sql);

foreach($rows as $row){
  $stmt->execute($row);
}

或者,像这样?

$sql = "insert into `table_name` (col1, col2, col3) values ";
$sql .= //not sure the best way to concatenate all the values, use implode?
$db->prepare($sql)->execute();

哪种方式更快更安全?插入多行的最佳方法是什么?

4 个答案:

答案 0 :(得分:6)

您至少有以下两个选项:

$rows = [(1,2,3), (4,5,6), (7,8,9) ... ];

$sql = "insert into `table_name` (col1, col2, col3) values (?,?,?)";

$stmt = $db->prepare($sql);

foreach($rows as $row)
{
    $stmt->execute($row);
}

OR:

$rows = [(1,2,3), (4,5,6), (7,8,9) ... ];

$sql = "insert into `table_name` (col1, col2, col3) values ";

$paramArray = array();

$sqlArray = array();

foreach($rows as $row)
{
    $sqlArray[] = '(' . implode(',', array_fill(0, count($row), '?')) . ')';

    foreach($row as $element)
    {
        $paramArray[] = $element;
    }
}

// $sqlArray will look like: ["(?,?,?)", "(?,?,?)", ... ]

// Your $paramArray will basically be a flattened version of $rows.

$sql .= implode(',', $sqlArray);

$stmt = $db->prepare($sql);

$stmt->execute($paramArray);

正如您所看到的,第一个版本的代码更简单;但是第二个版本确实执行批量插入。批量插入应该更快,但我同意 @BillKarwin ,绝大多数实现都不会注意到性能差异。

答案 1 :(得分:5)

我会以第一种方式进行,使用一行参数占位符准备语句,并使用execute一次插入一行。

$stmt = $db->prepare($sql);

foreach($rows as $row){
    $stmt-> execute($row);
}

它不如单个插入中的多行快,但它足够接近你可能永远不会注意到差异。

这样做的好处是可以很容易地使用代码。这就是为什么你要使用PHP,因为开发人员的效率,而不是运行时效率。

如果您有多个行(数百或数千),并且性能优先,则应考虑使用LOAD DATA INFILE

答案 2 :(得分:3)

你也可以这样:

<?php
$qmarks = '(?,?,?)'. str_repeat(',(?,?,?)', count($rows)-1);

$sql = "INSERT INTO `table`(col1,col2,col3) VALUES $qmarks";
$vals = array();
foreach($rows as $row)
    $vals = array_merge($vals, $row);
$db->prepare($sql)->execute($vals);

老实说,我不知道哪一个会更快,一切都取决于mysql和php服务器之间的延迟。

答案 3 :(得分:0)

/* test.php */

<?php
require_once('Database.php');

$obj = new Database();
$table = "test";

$rows = array(
    array(
    'name' => 'balasubramani',
    'status' => 1
    ),
    array(
    'name' => 'balakumar',
    'status' => 1
    ),
    array(
    'name' => 'mani',
    'status' => 1
    )
);

var_dump($obj->insertMultiple($table,$rows));
?>

/* Database.php */
<?php
class Database 
{

    /* Initializing Database Information */

    var $host = 'localhost';
    var $user = 'root';
    var $pass = '';
    var $database = "database";
    var $dbh;

    /* Connecting Datbase */

    public function __construct(){
        try {
            $this->dbh = new PDO('mysql:host='.$this->host.';dbname='.$this->database.'', $this->user, $this->pass);
            //print "Connected Successfully";
        } 
        catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "<br/>";
            die();
        }
    }
/* Insert Multiple Rows in a table */

    public function insertMultiple($table,$rows){

        $this->dbh->beginTransaction(); // also helps speed up your inserts.
        $insert_values = array();
        foreach($rows as $d){
            $question_marks[] = '('  . $this->placeholders('?', sizeof($d)) . ')';
            $insert_values = array_merge($insert_values, array_values($d));
            $datafields = array_keys($d);
        }

        $sql = "INSERT INTO $table (" . implode(",", $datafields ) . ") VALUES " . implode(',', $question_marks);

        $stmt = $this->dbh->prepare ($sql);
        try {
            $stmt->execute($insert_values);
        } catch (PDOException $e){
            echo $e->getMessage();
        }
        return $this->dbh->commit();
    }

    /*  placeholders for prepared statements like (?,?,?)  */

    function placeholders($text, $count=0, $separator=","){
        $result = array();
        if($count > 0){
            for($x=0; $x<$count; $x++){
                $result[] = $text;
            }
        }

        return implode($separator, $result);
    }

}
?>

以上代码应该是使用PDO插入多个记录的好方法。