PHP MySQL批量插入,带有准备好的语句

PHP MySQL批量插入,带有准备好的语句,php,mysql,prepared-statement,bulkinsert,Php,Mysql,Prepared Statement,Bulkinsert,我有一个脚本,可以插入大量的数据。此数据主要是上一次插入的复制,但至少有一个值不同。因此,我准备语句并绑定参数以执行和重复 然而,我试图将其写入一个准备好的批插入,一次插入1000行。不幸的是,我不能让它工作。我现在使用的代码只是一次插入整个数据。但是,这并不是我们想要的,因为数据量可能比测试数据量大得多 我现在使用的代码(一次性大容量插入): 我想要实现的是,数据将使用如上所述的准备好的语句插入,但每个批的限制为1000(或任何其他数字)。我不能让它工作。我尝试使用阵列拼接和其他方法,但无法使

我有一个脚本,可以插入大量的数据。此数据主要是上一次插入的复制,但至少有一个值不同。因此,我准备语句并绑定参数以执行和重复

然而,我试图将其写入一个准备好的批插入,一次插入1000行。不幸的是,我不能让它工作。我现在使用的代码只是一次插入整个数据。但是,这并不是我们想要的,因为数据量可能比测试数据量大得多

我现在使用的代码(一次性大容量插入):


我想要实现的是,数据将使用如上所述的准备好的语句插入,但每个批的限制为1000(或任何其他数字)。我不能让它工作。我尝试使用
阵列拼接
和其他方法,但无法使其工作。

与其尝试添加更多阵列副本,不如使用simple for loops分段工作:

$arraySize = count($Data);
for ( $i = 0; $i < $arraySize; $i+=1000 )    {
  // Number of elements in this chunk
  $thisChunk = min(1000, $arraySize-$i);
  // Prepare your statement
  $sql = $mysqli->prepare("INSERT INTO `Table` (Col1, Col2, Col3, Col4) VALUES ".implode(', ', array_fill(0, $thisChunk, "(?, ?, ?, ?)")));
  for( $j = $i; $i < $i + $thisChunk; $j++ )  {
    // Bind this data from $Data[$j]
  }
}
$arraySize=count($Data);
对于($i=0;$i<$arraySize;$i+=1000){
//此块中的元素数
$thisChunk=min(1000,$arraySize-$i);
//准备你的陈述
$sql=$mysqli->prepare(“插入到`Table`(Col1,Col2,Col3,Col4)值中”)。内爆(',',数组填充(0,$thishchunk,“(,,,,,,,?)”);
对于($j=$i;$i<$i+$thisChunk;$j++){
//从$data[$j]绑定此数据
}
}

当然,每次都会重新准备语句,如果您知道ThishChunk有1000个元素长,则可以避免这种情况。

您可以使用simple for循环分段工作,而不是尝试添加更多的数组副本:

$arraySize = count($Data);
for ( $i = 0; $i < $arraySize; $i+=1000 )    {
  // Number of elements in this chunk
  $thisChunk = min(1000, $arraySize-$i);
  // Prepare your statement
  $sql = $mysqli->prepare("INSERT INTO `Table` (Col1, Col2, Col3, Col4) VALUES ".implode(', ', array_fill(0, $thisChunk, "(?, ?, ?, ?)")));
  for( $j = $i; $i < $i + $thisChunk; $j++ )  {
    // Bind this data from $Data[$j]
  }
}
$arraySize=count($Data);
对于($i=0;$i<$arraySize;$i+=1000){
//此块中的元素数
$thisChunk=min(1000,$arraySize-$i);
//准备你的陈述
$sql=$mysqli->prepare(“插入到`Table`(Col1,Col2,Col3,Col4)值中”)。内爆(',',数组填充(0,$thishchunk,“(,,,,,,,?)”);
对于($j=$i;$i<$i+$thisChunk;$j++){
//从$data[$j]绑定此数据
}
}

这当然会重新准备你的陈述,如果你知道这个块是长1000个元素,你可以避免它。

< P>你应该考虑使用加载数据。p> 即使您必须先写出一个临时文件,它也可能比对成批行使用INSERT快得多

$Data = array(
    array("1", "2", "3", "4"),
    array("1", "2", "3", "5"),
    array("1", "2", "3", "6"),
    array("1", "2", "3", "7"),
    array("1", "2", "3", "8"),
    //ETC
    );

$tempname = tempnam("/tmp", "data");
$fp = fopen($tempname, "w");
foreach ($Data as $fields) {
    fputcsv($fp, $fields);
}
fclose($fp);
if ($mysqli->query("
  LOAD DATA INFILE '$tempname' INTO TABLE `Table`
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"'
  ") === false) {
    error_log($mysqli->error);
}
unlink($tempname);

阅读以确保您理解“代码>本地代码/代码>选项和<代码> Loall IfIs< /COD>和<代码> SeCURIOFILIVELIPIV CONFIG选项。

< P>您应该考虑使用加载数据。p> 即使您必须先写出一个临时文件,它也可能比对成批行使用INSERT快得多

$Data = array(
    array("1", "2", "3", "4"),
    array("1", "2", "3", "5"),
    array("1", "2", "3", "6"),
    array("1", "2", "3", "7"),
    array("1", "2", "3", "8"),
    //ETC
    );

$tempname = tempnam("/tmp", "data");
$fp = fopen($tempname, "w");
foreach ($Data as $fields) {
    fputcsv($fp, $fields);
}
fclose($fp);
if ($mysqli->query("
  LOAD DATA INFILE '$tempname' INTO TABLE `Table`
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"'
  ") === false) {
    error_log($mysqli->error);
}
unlink($tempname);

阅读以确保您了解
LOCAL
选项和
LOCAL\u infle
secure\u file\u priv
配置选项。我有一个问题。绑定返回的变量数与准备语句中的参数数不匹配。这是因为在
$Data[$j]
循环中,我一次绑定4个参数。我应该如何解决这个问题?例如,您能否向代码展示您希望我如何绑定
$Data[$j]
参数?您必须建立一个值数组,并使用
调用用户函数数组(array($stmt,'bindparams'),$array\u of_params)
将它们全部链接到语句。另一种选择是移动到PDO,在那里你可以一次链接一个。谢谢PDO!现在我可以在循环中绑定参数,并在完成时执行语句。谢谢我有一个问题。绑定返回的变量数与准备语句中的参数数不匹配。这是因为在
$Data[$j]
循环中,我一次绑定4个参数。我应该如何解决这个问题?例如,您能否向代码展示您希望我如何绑定
$Data[$j]
参数?您必须建立一个值数组,并使用
调用用户函数数组(array($stmt,'bindparams'),$array\u of_params)
将它们全部链接到语句。另一种选择是移动到PDO,在那里你可以一次链接一个。谢谢PDO!现在我可以在循环中绑定参数,并在完成时执行语句。谢谢