我想将数据插入到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;
结果如下:
答案 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 Update和Alter 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
部分什么都不做。