在插入[mysql_errno()]之前检查预先存在的记录的最快方法

时间:2012-01-18 14:19:40

标签: php mysql error-handling insert unique-constraint

我的问题将以电子邮件为例,但这可能适用于任何事情。


通常在注册新用户(包括插入他/她的电子邮件)之前,我会检查他/她的电子邮件是否已存在于DB中,如下所示:

$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
}

由于我已经将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

  

SQLSTATE值的前两个字符表示错误类:

     

Class = '00'表示成功。

     

Class ='01'表示警告。

     

Class = '02'表示“未找到。”这与游标的上下文相关,用于控制光标到达数据集末尾时发生的情况。对于不检索任何行的SELECT ... INTO var_list语句,也会出现这种情况。

     

类&gt; '02'表示例外。

2 个答案:

答案 0 :(得分:5)

使用

INSERT IGNORE INTO Users VALUES(...);

在电子邮件字段上使用唯一键,然后使用mysql_affected_rows()检查行计数;

这将导致对DB的单个查询并排除SELECT和INSERT之间时间窗口的竞争条件

答案 1 :(得分:0)

我相信COUNT是最快捷的方法之一。还记得在做你的查询时,如果你只想测试它的存在就不要做了

SELECT *

而是指定特定字段

SELECT id

所以你没有检索到那么多的数据。在使用COUNT的情况下:

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

请参阅以下有关如何在结果集中使用COUNT的链接

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