2012-01-18 15 views
0

私の質問ではメールを例として使用しますが、[mysql_errno()] [mysql_errno()]を挿入する前に既存のレコードを確認する最も簡単な方法

$result = mysql_query("SELECT * FROM Users WHERE email = '".mysql_real_escape_string($email)"';"); 
if(!$result) 
{ 
    die(mysql_error()); 
} 

if(mysql_num_rows($result) > 0) 
{ 
    die('<p>Email already in DB. <a....>Recover Email</a></p>'); 
} 
else 
{ 
    //insert new user data into Users table 
} 

私は「ので:


通常は新規ユーザーを登録する前に、彼/彼女のメールはすでにこのようなDB何かに存在する場合、私がチェック(彼/彼女のメールを挿入含みます) dは、私のUsersテーブルのemailフィールドをUNIQUEに制限しています。最初に挿入しようとするのが速くなく、失敗した場合はエラーをチェックしますか?このような何か:

$result = mysql_query(...);//insert new user data into Users table 
if(!$result) 
{ 
    if(mysql_errno()==$insert_unique_error) 
    { 
     $error = '<p>Email already in DB. <a....>Recover Email</a></p>'; 
    } 
    else 
    { 
     $error = mysql_error(); 
    } 
    die($die_str); 
} 

問題がどうあるべきか$insert_unique_error私はを知らないということです。これらは、エラーコードI could find次のとおりです。

The first two characters of an SQLSTATE value indicate the error class:

Class = '00' indicates success.

Class = '01' indicates a warning.

Class = '02' indicates “not found.” This is relevant within the context of cursors and is used to control what happens when a cursor reaches the end of a data set. This condition also occurs for SELECT ... INTO var_list statements that retrieve no rows.

Class > '02' indicates an exception.

+1

を設定し、なぜそれ? –

+0

@DamienPirsy通常の方法では、電子メールがまだ存在しないとき(select + insert)とそれが実行されたとき(select)の2つのクエリを行います。私が提案した解決策は、電子メールが存在するかどうかにかかわらず、1つのクエリを実行するだけです(挿入する)。 –

+0

私はそれがだと思っています: エラー:1092 SQLSTATE:HY000(ER_INSERT_INFO) メッセージ:レコード:%ld個の重複:%ldの警告:%ldの あなたのメールフィールドは一意である必要があります。 – CSharpRU

答えて

5

使用

INSERT IGNORE INTO Users VALUES(...); 

電子メールフィールドに一意のキーで、その後(にmysql_affected_rowsで行数を確認してください)。

これは、DBへの単一のクエリの結果とSELECTの間の時間窓の競合状態を排除し、私はそのCOUNTが最速の方法の一つであると考えてい

+0

もちろん、 'mysql_affected_rows()'、ugh。なぜ 'INSERT ...'だけでなく、 'INSERT IGNORE ...'を使うのでしょうか?それは競争条件を排除する特定の部分/キーワードですか? –

+0

重複キーが検出された場合、INSERTはクエリを失敗させますが、INSERT IGNOREは行を無視して成功させます。あなたは両方を使うことができますが、クエリが意図的に失敗するのが私の好みのためには最良のスタイルではありません。 –

+0

私は2つの違いの重要性を見ません。'mysql_affected_rows()'を使うつもりなら、 'if(!$ result)'をチェックしないで、成功したか失敗したかはわかりません。 。右?または私はここに何かを逃していますか? –

0

を挿入します。あなたのクエリを実行するときにのみ、その代わりですから、できるだけ多くのデータを取得していない特定のフィールド

SELECT id 

を指定

SELECT * 

をしないその存在をテストしたい場合にも、覚えておいてください。 COUNTを使用する場合には:

SELECT COUNT(id) FROM Users WHERE email = 'emailaddress' 

が結果にCOUNTを使用する方法については下のリンクを参照してくださいあなたはまだ1つのクエリをやっている

http://www.tizag.com/mysqlTutorial/mysqlcount.php

+0

私は '*'の代わりに 'ID'を使うことに同意します(私はこれを普通にやります)、' COUNT() 'は' mysql_num_rows() 'よりも速いかもしれません。 'SELECT'を全く避けてください。 –

+0

ああ、それは余分なクエリ(と少ないリーンコード)が必要ですが、私は選択したものを使用することを好むよりもむしろ、それがクリーナーであると私にはより論理的なように挿入時にスローされるエラーに頼るより好む。私は実際には、余分な選択があまりにも多くのオーバーヘッドを追加する状況を実際に遭遇していない – acSlater

関連する問題