为什么这个PDO Insert执行两次?

时间:2014-06-08 17:38:29

标签: php mysql while-loop fgetcsv

这已经将csv中的每一行插入数据库两次,现在已经三次。我放在循环中的其他任何事情都不会发生。

$file_handle = fopen("uploads/numbers.csv", "r");    
$stmt = $db->prepare("INSERT INTO database
(firstname,lastname,phonenumber) VALUES
(:field1,:field2,:field3)");

while (($line_of_data = fgetcsv($file_handle, 1000, ",")) !== FALSE) 
{
$stmt->execute(array(':field1' => $line_of_data [0], ':field2' => $line_of_data[1], ':field3' => $line_of_data[2]));
}

2 个答案:

答案 0 :(得分:0)

在数据库上设置正确的主键。 (名字,姓氏)或(名字,姓氏,电话号码)取决于用法。 Ta-da,不再重复。

由于CSV包含数据库中预先存在的数据,我将假设詹姆斯在列中是正确的,但不管怎样,主键都可以防止重复。

如果您使用firstname,lastname键并且希望脚本能够更新电话号码,则可以使用REPLACE而不是INSERT。

答案 1 :(得分:0)

您的支票在这里:

while (($line_of_data = fgetcsv($file_handle, 1000, ",")) !== FALSE) 

首先,您不需要!== FALSE。它可以是这样的:

while (($line_of_data = fgetcsv($file_handle, 1000, ","))) 

此外,您的代码只是检查while fgetcsv是否为空。那么如果文件中有空行怎么办?它运行两次。那怎么样:

while (($line_of_data = trim(fgetcsv($file_handle, 1000, ",")))) {
  if (!empty($line_of_data)) {
    $stmt->execute(array(':field1' => $line_of_data [0], ':field2' => $line_of_data[1], ':field3' => $line_of_data[2]));
  }
}

这个想法是,当你打电话给fgetcsv时,让我们修剪一行,以摆脱额外的东西,比如在行尾可能换行。然后if (!empty($line_of_data)) {检查该行是否为空&只有在绝对不为空的情况下才会对查询起作用。如果以某种方式trim(fgetcsv(…))不起作用,你可以这样做:

while (($line_of_data = fgetcsv($file_handle, 1000, ","))) {
  if (!empty(trim($line_of_data))) {
    $stmt->execute(array(':field1' => $line_of_data [0], ':field2' => $line_of_data[1], ':field3' => $line_of_data[2]));
  }
}

使用if (!empty(trim($line_of_data))) {中的所有逻辑。