web-dev-qa-db-ja.com

挿入する前に重複を確認してください

データベースに挿入する前に、次のコードを使用して重複をチェックしています。私にとって、重複は、namedescriptionpricecity、およびenddateが一致する場合にのみ重複と見なされます。

foreach($states_to_add as $item) {
    $dupesql = "SELECT 
                    COUNT(*) 
                FROM 
                    table 
                WHERE 
                    (   
                        name = '$name' 
                        AND description = '$description' 
                        AND manufacturer = '$manufacturer' 
                        AND city ='$city' 
                        AND price = '$price' 
                        AND enddate = '$end_date'
                    )";

    $duperaw = mysql_query($dupesql);

    if($duperaw > 0) {
        echo nl2br("$name already exists in $city \n");
    } 
    else {
        $sql = "INSERT INTO table (..... (here go the values to be inserted)
        ....

各値は、このチェックを実行する前に定義されます。アイテムが既に存在するため、結果は常に返されます。 「dupesql」をダンプし、コマンドをコピーしてphpmyadminに貼り付けました。phpmyadminはカウント0で返されます。

8
Mike

次のことを行います。

$dupesql = "SELECT * FROM table where (name = '$name' AND description = '$description' AND manufacturer = '$manufacturer' AND city ='$city' AND price = '$price' AND enddate = '$end_date')";

$duperaw = mysql_query($dupesql);

if (mysql_num_rows($duperaw) > 0) {
  //your code ...
}

詳細については、 ここ を参照してください。

15
hoppa

私が見ているように、あなたの質問は2つの部分に分けることができます。私のPHPコードが機能しないのはなぜですか?わからない、よくわからないPHPそして他の人はちょうどそれに答えたようです:-) 。2番目の質問は、重複をチェックするにはどうすればよいですか?完全に間違った方法で重複をチェックしています。

テーブルに 一意のインデックス / 主キー を作成します。次に、DBを挿入しようとすると、重複がある場合にエラーがスローされます。エラーをキャッチし、必要に応じて対処します。レコードの数を数えることは間違いなく間違った方法であり、コードの速度に重大な悪影響を及ぼします。

6
Ben

2人のユーザーが同時に重複を挿入しようとする競合状態が発生する可能性があります。selectステートメントを使用して重複をチェックすると、両方のユーザーがレコードを挿入できるようになります。 DBに一意のインデックスを設定してから、DBから発生するエラーをキャッチすることを好みます。

1
Homan

PHPで一意性をチェックする必要はなく、MySQLでテスト全体を実行できます。

INSERT INTO table1 (name, description, ......)
  SELECT name1, description1, manufacturer1, city1, price1, enddate1
  FROM (SELECT * FROM ( 
    SELECT 
      @name:= '$name' as name1
      ,@description:= '$description' as description1
      ,.....
    FROM DUAL as d1
    LEFT JOIN table1 t1 
           ON (t1.name = d1.name1 
          AND t1.description = d1.description1
          AND ......)
    WHERE t1.name IS NULL) s1) s2

これは、一意性テストに合格した場合にのみ値を挿入します。

フォローしてみてください

  INSERT IGNORE INTO person_tbl (last_name, first_name) 
  -> VALUES( 'Jay', 'Thomas');
0

これを試してください:

foreach($states_to_add as $item) {
    $dupesql = "SELECT 
                    name 
                FROM 
                    table 
                WHERE 
                    (name = '$name' 
                        AND description = '$description' 
                        AND manufacturer = '$manufacturer' 
                        AND city ='$city'
                        AND price = '$price' 
                        AND enddate = '$end_date'
                    )";

    $duperaw = mysql_query($dupesql);

    if( mysql_num_rows($duperaw) ) {
        echo nl2br("$name already exists in $city \n");
    } 
    else {
        $sql = "INSERT INTO table (..... (here go the values to be inserted)
0
Puzo

つまり、PHPを介してチェックを行う必要があります。また、両方の長所を活用するには、MySQLテーブルに複合一意制約を追加する必要があります。

あなたの質問を2つの別々の質問に分解するとよいでしょう。

1- PHPを使用して重複をチェックし、クエリを実行する前にユーザーについて通知するにはどうすればよいですか?2-MySQLで複合一意制約を指定するにはどうすればよいですか?

まず、次のような単純なPHP関数を使用して、このレコードがDBに存在するかどうかを確認する必要があります。

function is_exist($table, $data){
    $sql = "SELECT * FROM `" . $table . "` WHERE ";

    foreach ($data as $key => $val) :
    $sql .= "`$key`='" . $val . "' AND ";
    endforeach;

    $sql = substr($sql,0, -5);

    $result = $mysql_query($sql);
    $count = $mysql_num_rows($result);

    return ($count > 0) ? true: false;
}   

以下のようにPHP関数を呼び出す必要があります:

    $data = array('column1'=>$_POST['value'],'column2'=>$_POST['value'], ...);

    if(is_exist($data)){
      // Print your error message
    }else{
     // Run your insert query
    }

このようにして、MySqlデータベースに移動する前に重複を防ぐことができますが、無料のデータベースを重複させるには、MySQLテーブルに複合一意制約を追加する必要があります。

この単純なSQLコマンドでトリックを実行できます。

alter table `tablename` add unique index(name, description, manufacturer, city, price, enddate);

それがお役に立てば幸いです。何か混乱した場合は、私に負担をかけてください。

0
EKY