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_id行を挿入する前に、同じと。の行を明示的にチェックするため、これは混乱を招きます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 に答える