如何防止重复插入表中

时间:2015-10-24 13:26:30

标签: php mysql pdo

我想将数据插入到Mysql中,当数据已经在表中时,不应再次插入。如何防止第二次插入?

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "INSERT INTO MyGuests(firstname, lastname, email)
    VALUES ('John', 'Doe', 'john@example.com')";

    // use exec() because no results are returned
    $conn->exec($sql);
    echo "Table MyGuests created successfully";
} catch(PDOException $e) {
    echo $sql . "<br>" . $e->getMessage();
}

$conn = null;

结果如下:

enter image description here

2 个答案:

答案 0 :(得分:0)

电子邮件地址上没有唯一键。这是你最好的希望,因为许多John Doe都可以在系统中。因此,全名的唯一复合索引并不是一个好主意。

可以发出一个INSERT IGNORE,它会在重复违规之后发生变化,好像什么也没发生(这是非常不推荐的,在您的情况下不可能,因为您对电子邮件的唯一约束不存在)。这样做的主要问题是你的倾向(阅读:可能会)失去对正在发生的事情流的所有控制,并留下不需要的数据。所以不要使用它,除非你是专业人士。

可以发出INSERT ON DUPLICATE KEY UPDATE(a.k.a. IODKU)也需要一个唯一的密钥(也可以是一个独特的复合)。因此,不会发生新行,而是对行进行更新。例如,可以插入一个包含4列的新行,但在复制违规时,只能对其中两列执行更新,例如

假设在看不见的列id int下方的PK下方,以及emailAddr上的唯一键

insert person(firstName,lastName,emailAddr) values 'Joe','Smith','jsmith@email.com' 
on duplicate key update firstName='Joe',lastName='Smith'

这是emailAddr上的唯一键,使其成功。每封emailAddr只留下一行。

所以,你可以拥有无​​限的Joe Smiths,但每个电子邮件地址只有1行。

上表的创建表可能类似于

create table person
(  id int auto_increment primary key,
   firstName varchar(50) not null,
   lastName varchar(50) not null,
   emailAddr varchar(150) not null,
   unique key(emailAddr)  -- without this, IODKU will not work
);

您还可以在创建表后发出ALTER TABLE命令以添加约束。根据其中的数据,呼叫可能会失败。

Mysql Insert on Duplicate Key UpdateAlter Table手册页。

我会再说一遍,如果没有正确的架构设置,IODKU将无法工作,您将留下不受欢迎的行。所以不要对它懒惰。设置架构首先允许它成功(使用唯一键),然后继续使用IODKU。

答案 1 :(得分:0)

您需要添加唯一约束/索引并忽略由复制引起的错误。如果这是您的查询:

INSERT INTO MyGuests(firstname, lastname, email)
    VALUES ('John', 'Doe', 'john@example.com');

并且您希望阻止重新插入所有三列,然后您可以添加唯一的:

create unique index unq_myguests_firstname_lastname_email on myguests(firstname, lastname, email);

然后,将insert标记为:

INSERT INTO MyGuests(firstname, lastname, email)
    VALUES ('John', 'Doe', 'john@example.com')
    ON DUPLICATE KEY UPDATE firstname = VALUES(firstname);

除了忽略错误之外,ON DUPLICATE KEY UPDATE部分什么都不做。