如果没有重复,如何插入?

时间:2014-07-04 20:08:10

标签: php mysql sql pdo

如果数据库中没有相同的电子邮件用户,我只想插入新用户。

我正在阅读这篇文章:MySQL - ignore insert error: duplicate entry但问题是在执行sql语句后,我不知道新用户是否成功插入。

3 个答案:

答案 0 :(得分:4)

  

执行sql语句后,我不知道是不是   成功与否

如果我理解正确,您想知道在使用INSERT IGNORE后是否发生了插入。执行查询后调用LAST_INSERT_ID(),如果返回0,则表示未插入行。

https://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

  

如果使用INSERT IGNORE并忽略该行,则为AUTO_INCREMENT   计数器没有递增,LAST_INSERT_ID()返回0,这   反映没有插入行。

<强>测试

mysql> insert ignore into example (`id`, `data`) VALUES (2,'hello');
Query OK, 1 row affected (0.04 sec)

mysql> insert ignore into example (`id`, `data`) VALUES (3,'hello');
Query OK, 1 row affected (0.06 sec)

mysql> insert ignore into example (`id`, `data`) VALUES (2,'hello');
Query OK, 0 rows affected (0.00 sec)

mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                0 |
+------------------+
1 row in set (0.00 sec)

警告

某些版本的MySQL存在last_insert_id()无法与INSERT IGNORE正常工作的错误:http://bugs.mysql.com/bug.php?id=67535

答案 1 :(得分:2)

只需进行常规插入,然后检查错误代码:

$result = mysql_query("INSERT ... stuff that causes duplicate key error");
if (mysql_errno() == 1022) {
   ... account already exists ...
}

这比先选择“选择”以查看电子邮件是否存在,然后插入(如果不存在)更安全。另一个并行请求可能会从您的下方“窃取”该帐户。

这里记录了mysql错误代码:http://dev.mysql.com/doc/refman/5.0/en/error-messages-server.html


评论后续:

在某些情况下,我的回答可能更可靠,例如考虑一下:

mysql> create table foo (x int primary key auto_increment, y  text);
Query OK, 0 rows affected (0.00 sec)

mysql> insert into foo (y) values ('bar1'); // id #1
Query OK, 1 row affected (0.00 sec)

mysql> insert into foo (y) values ('bar2'); // id #2
Query OK, 1 row affected (0.00 sec)

mysql> insert into foo (x,y) values (2, 'bar2'); // try to create a dupe id #2
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                2 |
+------------------+
1 row in set (0.00 sec)

注意你仍然得到一个last_insert_id()。那是因为它始终是最后 SUCCESSFUL 插入的值。由于插入失败,该值不会重置。

如果您使用数据库句柄进行多次插入,并尝试使用if last_insert_id == 0技巧,那么您可能会得到一个错误的答案,因为您将获得一些成功的OTHER插入的ID,不是那个刚失败的人。

请注意insert ignore也无济于事:

mysql> insert ignore into foo (x,y) values (1, 'bar1'); // create dupe id #1
Query OK, 0 rows affected (0.00 sec)

mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                2 |
+------------------+
1 row in set (0.00 sec)

答案 2 :(得分:1)

如果你使用 PDO ,那很简单:

try{
   // INSERT new account
}
catch(PDOException $ex){ /* already exist -> errorInfo */ }

如果你有:

    电子邮件字段的
  • UQ
  • attr mode$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

全部


<强>加入:

以防正确理解 - see comment

任何DB-Layer,例如:

class TableExample
{
    ...    
    // sample with inner logic
    public function createUser(...)
    {
        ...
        $this->db->query("INSERT INTO ...");
        ...
    }

    // sample with the AR etc.
    public function updateFooBar(...)
    {
        ...
        $user->name  = 'name';
        $user->email = 'email';
        $user->save();
        ...
    }    
}

某些X层:

class ModelStuff
{
    ....
    public function foo()
    {
        try{
            $this->example->createUser();
            ...
            $this->example->updateFooBar();
            ...
        }
        catch(PDOException $ex){
            // TODO: e.g. ($ex->getCode() == 23000)? ...
            // all PDOException with TableExample catched here
        }
    }
}

编译了我的所有评论: