2012-01-18 3 views
0

제 질문은 이메일을 예로 들겠습니다. 그러나 이것은 무엇이든 적용 할 수 있습니다.삽입하기 전에 기존 레코드를 확인하는 가장 빠른 방법 [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는 내 사용자 테이블의 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가해야한다 무엇 를 모르는 것입니다. 다음() 있으며, mysql_affected_rows으로 계산 행을 확인 이메일 필드에 고유 키와

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) 두 번의 쿼리를 수행합니다. 내가 제안한 해결책은 전자 메일의 존재 여부와 상관없이 하나의 쿼리 만 수행합니다 (삽입). –

+0

나는 그것의 생각 해요 : 오류 : 1092 SQLSTATE : HY000 (ER_INSERT_INFO가) 메시지 : 레코드 : % ld 개 중복 : % ld 개 경고 : % ld 개 당신의 메일 필드가 고유해야합니다. – CSharpRU

답변

5

사용

INSERT IGNORE INTO Users VALUES(...); 

;이 유일한 오류 코드 I could find 있습니다

이는 DB에 단일 쿼리 결과와 SELECT 사이의 시간 윈도우의 경쟁 조건을 배제하고

+0

물론,'mysql_affected_rows()', 우. 왜'INSERT ... '가 아닌'INSERT IGNORE ...'인가? 경쟁 조건을 배제하는 특정 부분/키워드입니까? –

+0

INSERT는 중복 키를 발견하면 쿼리를 실패하게하지만 INSERT IGNORE는 행을 무시하는 동안 성공하게합니다. 두 가지를 모두 사용할 수는 있지만 질의에 고의적으로 실패하는 것은 내가 가장 좋아하는 스타일이 아닙니다. –

+0

둘 사이의 차이점에서 중요성을 느끼지 않습니다.'mysql_affected_rows()'를 사용하려고한다면'if (! $ result)'를 체크하지 않기 때문에 성공했는지 실패했는지 신경 쓰지 않아 영향받은 행을 검사 할 것입니다. . 권리? 아니면 여기에 뭔가 빠졌나요? –

0

내가 그 수가 가장 빠른 방법 중 하나라고 생각 삽입합니다. 쿼리를 수행 할 때 당신은 단지 대신 그래서 당신은 많은 데이터를 검색하지 않는 특정 분야

SELECT id 

을 지정

SELECT * 

하지 않는 그 존재를 테스트하려는 경우 또한, 기억. COUNT를 사용하는 경우 :

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

이 결과에 COUNT를 사용하는 방법에 대한 아래 링크를 참조하시기 바랍니다 당신은 여전히 ​​하나 개의 쿼리를하고있는

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

+0

'*'대신'ID'를 사용하는 것에 동의합니다. (보통은 질문에 넣은 것을 잊었습니다.)'COUNT()'는 mysql_num_rows()보다 빠르지 만 실제로 찾고 있습니다. 'SELECT'를 피하십시오. –

+0

아, 비록 여분의 쿼리 (그리고 적은 양의 코드가 필요함)가 필요하지만, 먼저 선택을 사용하는 것이 더 낫다. 나는 실제로 여분의 선택이 너무 많은 오버 헤드를 추가하는 상황에 직면하지 않았다. – acSlater

관련 문제