说,我们在表中插入了多行:
$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();
哪种方式更快更安全?插入多行的最佳方法是什么?
答案 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插入多个记录的好方法。