0

我有以下代码:

$sth = $dbh->prepare("SELECT * FROM stats WHERE player_id = :player_id AND data_type = :data_type");

$sth->bindParam(':player_id', $player_id);
$sth->bindParam(':data_type', $total_time_data_type_id);
$sth->execute();

$result = $sth->fetch();            

if(!$result){
    $sth = $dbh->prepare("INSERT INTO stats (player_id, offset, created, modified, last_check, data_type, data) VALUES (:player_id, :offset, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), '1', :total_time_data_type_id, '0')");

    $sth->bindParam(':player_id', $player_id);
    $sth->bindParam(':offset', $offset);
    $sth->bindParam(':total_time_data_type_id', $total_time_data_type_id);
    $sth->execute();

    if(!$sth){
        return false;
    }
    $sth = $dbh->prepare("SELECT * FROM stats WHERE player_id = :player_id AND data_type = :data_type");

    $sth->bindParam(':player_id', $player_id);
    $sth->bindParam(':data_type', $total_time_data_type_id);
    $sth->execute();

    $result = $sth->fetch();
    if(!$result){
        return false;
    }
}else{
    $sth = $dbh->prepare("UPDATE stats SET .....");
    //Do more stuff
}

现在,有时这会创建重复的行(在大约 600 行中,有 23 个重复)。这让我感到困惑,因为在插入行之前,我明确检查了具有相同player_idand的行data_type

player_id相同的或可以存在多行data_type,但每行不一样。

IE 这将是有效的:

ID | PLAYER_ID | DATA_TYPE
---|-----------|----------
1  | 15        | 7
2  | 15        | 18
3  | 92        | 7
4  | 115       | 23

虽然这不会:

ID | PLAYER_ID | DATA_TYPE
---|-----------|----------
1  | 15        | 7        
2  | 32        | 18       
3  | 15        | 7        
4  | 115       | 23

因此,我不能简单地将该player_id字段声明为唯一的。

我能想到的唯一可能导致此问题的事实是,上面的代码片段位于foreach平均大约 115 次迭代的循环内,并且在几秒钟内再次调用了此代码。有没有办法以编程方式防止这种情况?

4

1 回答 1

0

感谢大家的帮助,尤其是@nikita2206。这就是我解决问题的方法:

  1. 删除了作为主键的列 ID。
  2. 在(Player_id,data_type)上创建了新的主键。
  3. 更改了 INSERT 语句:

$sth = $dbh->prepare("INSERT INTO stats (player_id, offset, created, modified, last_check, data_type, data) VALUES (:player_id, :offset, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), '1', :total_time_data_type_id, '0')");

$sth = $dbh->prepare("INSERT INTO stats (player_id, offset, created, modified, last_check, data_type, data) VALUES (:player_id, :offset, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), '1', :total_time_data_type_id, '0') ON DUPLICATE KEY UPDATE player_id = player_id");

通过非常快速地多次调用代码进行了测试,并且没有创建重复项。

于 2012-11-25T19:19:14.973 回答