6

我有一个如下所示的 MySQL 查询:

INSERT INTO beer(name, type, alcohol_by_volume, description, image_url) VALUES('{$name}', {$type}, '{$alcohol_by_volume}', '{$description}', '{$image_url}')

唯一的问题是 name 是一个唯一值,这意味着如果我遇到重复项,我会收到如下错误:

Error storing beer data: Duplicate entry 'Hocus Pocus' for key 2

有没有办法确保 SQL 查询不会尝试添加已经存在的唯一值而不运行SELECT整个数据库的查询?

4

5 回答 5

8

您当然可以使用 INSERT IGNORE INTO,如下所示:

INSERT IGNORE INTO beer(name, type, alcohol_by_volume, description, image_url) VALUES('{$name}', {$type}, '{$alcohol_by_volume}', '{$description}', '{$image_url}')

你也可以使用ON DUPLICATE KEY,但如果你只是不想添加一行INSERT IGNORE INTO是更好的选择。ON DUPLICATE KEY如果您想在有重复项时做更具体的事情,则更适合。

如果您决定使用ON DUPLICATE KEY- 避免在具有多个唯一索引的表上使用此子句。如果您有一个包含多个唯一索引的表ON DUPLICATE KEY- 子句可能会产生意想不到的结果(您真的无法 100% 控制将要发生的事情)

示例: - 下面的这一行仅更新 ONE 行(如果 type 为 1 且 Alcohol_by_volume 为 1(并且两列都是唯一索引))

ON DUPLICATE KEY UPDATE beer SET type=3 WHERE type=1 or alcohol_by_volume=1

把它们加起来:

ON DUPLICATE KEY当有重复时,只是在没有警告或错误的情况下完成工作。

INSERT IGNORE INTO当有重复项时会发出警告,但除此之外,只需忽略将重复项插入数据库。

于 2013-05-02T12:56:47.670 回答
6

碰巧的是,在 MySQL 中有一种方法是使用ON DUPLICATE KEY UPDATE. 这从 MySQL 4.1 开始可用

INSERT INTO beer(name, type, alcohol_by_volume, description, image_url)
  VALUES('{$name}', {$type}, '{$alcohol_by_volume}', '{$description}',
  '{$image_url}')
  ON DUPLICATE KEY UPDATE type=type;

您也可以将INSERT IGNORE INTO...其用作替代方案,但该语句仍会引发警告(尽管不是错误)。

于 2013-05-02T12:56:31.620 回答
2

就在这里。您可以使用ON DUPLICATE KEYmysqlINSERT语句的子句。语法在这里解释

INSERT INTO beer(name, type, alcohol_by_volume, ...) 
  VALUES('{$name}', {$type}, '{$alcohol_by_volume}', ...)
  ON DUPLICATE KEY UPDATE 
     type={$type}, alcohol_by_volume = '{$alcohol_by_volume}', ... ;
于 2013-05-02T12:56:35.447 回答
0

是的,首先从数据库中选择名称,如果查询结果不为空(零记录),则该名称已经存在,您必须获取另一个名称。

于 2013-05-02T12:56:10.537 回答
0

很简单——如果某些东西试图插入重复的名称,你的代码需要弄清楚它想要做什么。因此,您首先需要做的是运行一个 select 语句:

 SELECT * FROM beer WHERE name='{$name}'

然后运行一个'if'语句来确定你是否得到了结果。

如果结果 = 0,则继续运行插入。否则……无论你想做什么。向用户抛出错误?以不同的方式修改数据库?完全无视吗?这个插入语句是如何产生的?从文件进行大规模更新?来自网页的用户输入?

你到达这个插入语句的方式,以及它应该如何影响你的工作流程,应该准确地确定你如何处理那个“其他”。但你绝对应该处理它。

但是只要确保 select 和 insert 语句一起在一个事务中,这样其他人进来做同样的事情就不是问题了。

于 2013-05-02T12:59:41.590 回答