以下方法来自我的 PDO 主力,用于批量插入。它创建具有多个 VALUES 条目的单个 INSERT 语句。
用它作为
$db->bulkinsert(
'tbl_my_tablename',
array('fieldname_1','fieldname_2', 'fieldname_3'),
array(
/* rec1 */ array('r1f1', 'r1f2', 'r1f3'),
/* rec2 */ array('r2f1', 'r2f2', 'r2f3'),
/* rec3 */ array('r3f1', 'r3f2', 'r3f3')
));
请注意,该方法是一个复杂类定义的片段,这里使用的一些方法没有包含在代码片段中,尤其是$this->connect()
(connects to PDO)、$this->begin()
(starts transaction)$this->commit()
和,以及类似于 Apache Commons 的 Logging$this->rollback()
静态类Log
;-)
但我敢肯定这是你可能需要的。
/**
* Performs fast bulk insertion
* Parameters:
* $tablename
* $datafields - non-assiciative array of fieldnames
* or propertynames if $data is an array of objects
* $data - array of either non-associative arrays (in the correct order)
* or array of objects with property names matching the $datafields array
*/
const MAX_BULK_DATA = 3000;
public function bulkinsert($tablename, $datafields, &$data) {
$result = 0;
try {
try {
$this->connect();
$datacount = count($data);
// loop until all data has been processed
$start = 0;
$lastbinds = 0;
$this->begin();
while ($start < $datacount) {
$ins = array();
$bindscount = min(self::MAX_BULK_DATA, $datacount - $start);
if ($bindscount != $lastbinds) {
// prepare the binds
$binds = substr(str_repeat(',?', count($datafields)), 1);
$binds = substr(str_repeat(",($binds)", $bindscount), 1);
$lastbinds = $bindscount;
}
for ($go = $start, $last = $start + $bindscount; $go < $last; $go++) {
if (is_object($data[$go])) {
try {
foreach($datafields as $propname) {
$rfl = new ReflectionProperty($data[$go], $propname);
$rfl->setAccessible(true);
$ins[] = $rfl->getValue($data[$go]);
}
}
catch(ReflectionException $e) {
throw new InvalidArgumentException('PDOCONNECT_ERR_SQL_UNKNOWN_PROPERTY', 0, $e);
}
}
else {
foreach($data[$go] as $value) {
$ins[] = $value;
}
}
}
$sql = sprintf('INSERT INTO %s (%s) VALUES %s', $tablename, join(',',$datafields), $binds);
Log::trace($sql);
$stmt = $this->pdo->prepare($sql);
$stmt->execute($ins);
$start = $last;
$result += $bindscount;
}
$this->commit();
}
catch(PDOException $e) {
// do something with the exception if necessary
throw $e;
}
}
catch(Exception $e) {
$this->rollback();
throw $e;
}
return $result;
}
}