使用PDO和包含所有数据库值的PHP变量批量插入

时间:2016-01-13 17:43:56

标签: php pdo bulkinsert

我是PHP的新手,我正在尝试将已弃用的代码从mysql更新为PDO。

考虑到变量$ insert包含批量插入的所有值,例如:

('82817cf5-52be-4ee4-953c-d3f4ed1459b0','1','EM3X001P.1a','04.03.10.42.00.02'),
('82817cf5-52be-4ee4-953c-d3f4ed1459b0','2','EM3X001P.2a','04.03.10.33.00.02'),

...等13k行插入

这是不推荐使用的代码:

mysql_connect('localhost', 'root', '') or die(mysql_error()); 
mysql_select_db("IPXTools") or die(mysql_error());

if ($insert != '')
{
  $insert = "INSERT INTO IPXTools.MSSWireList (ID,Record,VlookupNode,HostWireLocation) VALUES ".$insert;
  $insert .= "ON DUPLICATE KEY UPDATE Record=VALUES(Record),VlookupNode=VALUES(VlookupNode),HostWireLocation=VALUES(HostWireLocation)";

  mysql_query($insert) or die(mysql_error());
  $insert = '';
}

这是新代码:

try 
{
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);    
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);    //set the PDO error mode to exception

    // prepare sql and bind parameters
    $stmt = $conn->prepare("INSERT INTO IPXTools.MSSWireList (ID, Record, VlookupNode, HostWireLocation) 
    VALUES (:ID, :Record, :VlookupNode, :HostWireLocation)");
    $stmt->bindParam(':ID', $ID);
    $stmt->bindParam(':Record', $Record);
    $stmt->bindParam(':VlookupNode', $VlookupNode);
    $stmt->bindParam(':HostWireLocation', $HostWireLocation);    

    // insert a row
    // loop through all values inside the $insert variable??????? how?
    $stmt->execute();
}
catch(PDOException $e)
{
     echo "Error: " . $e->getMessage();
}
$conn = null;

在我的研究期间,我发现了一篇优秀的帖子: PDO Prepared Inserts multiple rows in single query

一种方法说我必须更改我的$ insert变量以包含所有字段名称。 而其他方法说我不必这样做。我正在看Chris M.建议:

  

当数据数组很小时,Herbert Balagtas的接受答案很有效。对于较大的$ data数组,array_merge函数变得非常慢。我创建$ data数组的测试文件有28个cols,大约是80,000行。最后的剧本需要41秒才能完成

但我不明白他在做什么,我正在努力使我的代码适应他的。 PHP sintax对我来说是新的,所以我对处理数组等感到不安...

我想起点是变量$ insert,它包含我需要的所有数据库值。 我是否需要修改$ insert变量以包含字段名称? 或者我可以只使用其内容并提取值(如何?)并将值包含在循环语句中? (这可能会在一次执行我的13k行)

谢谢

1 个答案:

答案 0 :(得分:1)

如果要插入13k记录,则不要使用准备好的SQL语句,这样做有利于提高性能。只需生成如下格式的SQL查询:

INSERT INTO IPXTools.MSSWireList 
(ID, Record, VlookupNode, HostWireLocation) 
VALUES 
('id1', 'r1', 'node1', 'location1'),
('id2', 'r2', 'node2', 'location2'),
...
('id13000', 'r13000', 'node13000', 'location13000');

您可以为此做些什么 - 使用遗留代码的主要内容。你的try区块会看起来像这样:

try 
{
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);    
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $conn->exec($insert);
}