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

发布于 2025-01-20 00:38:13 字数 613 浏览 4 评论 0原文

假设我们要在表中插入多行:

$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();

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

Say, we have multiple rows to be inserted in a table:

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

Using PDO:

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

Now, how should you proceed in inserting the rows? Like this?

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

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

or, like this?

$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();

Which way would be faster and safer? What is the best way to insert multiple rows?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

机场等船 2025-01-27 00:38:13

您至少有这两个选择:

$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 的观点,即在绝大多数实现中不会注意到性能差异。

You have at least these two options:

$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);

As you can see the first version features a lot simpler code; however the second version does execute a batch insert. The batch insert should be faster, but I agree with @BillKarwin that the performance difference will not be noticed in the vast majority of implementations.

-小熊_ 2025-01-27 00:38:13

我会采用第一种方法,用一行参数占位符准备语句,然后使用执行一次插入一行。

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

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

它不像在一次插入中执行多行那么快,但它足够接近,您可能永远不会注意到其中的差异。

这样做的优点是使用代码非常容易。这就是为什么您无论如何都要使用 PHP,是为了开发人员效率,而不是运行时效率。

如果您有许多行(数百或数千),并且性能是优先考虑的,您应该考虑使用加载数据文件

I would do it the first way, prepare the statement with one row of parameter placeholders, and insert one row at a time with execute.

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

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

It's not quite as fast as doing multiple rows in a single insert, but it's close enough that you will probably never notice the difference.

And this has the advantage that it's very easy to work with the code. That's why you're using PHP anyway, for the developer efficiency, not the runtime efficiency.

If you have many rows (hundreds or thousands), and performance is a priority, you should consider using LOAD DATA INFILE.

云柯 2025-01-27 00:38:13

你也可以这样走:

<?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服务器之间的延迟。

You can also go this way:

<?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);

To be honest, I don't know which one will be faster, all depends on the delay between mysql and the php server.

樱桃奶球 2025-01-27 00:38:13
/* 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 插入多条记录的良好解决方案。

/* 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);
    }

}
?>

The above code should be good solution for Inserting Multiple Records using PDO.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文