MySQL INSERT 与 ON DUPLICATE SELECT 可能吗?

Posted

技术标签:

【中文标题】MySQL INSERT 与 ON DUPLICATE SELECT 可能吗?【英文标题】:MySQL INSERT with ON DUPLICATE SELECT possible? 【发布时间】:2014-01-17 14:22:01 【问题描述】:
email_address
-------------
id
prefix
fqdn

前缀和 fqdn 共同构成一个唯一键。

如果电子邮件地址尚未在表中,我想编写一个插入查询。如果地址已经在表中,它应该返回 id。

如果合法的话,有没有办法编写一个类似于INSERT INTO email_address(prefix, fqdn) VALUES (?, ?) ON DUPLICATE SELECT id as LAST_INSERT_ID WHERE prefix = ? AND fqdn = ? 的查询?

基本上我想在一个查询中执行 INSERT SELECT。

【问题讨论】:

不,据我所知,这在 mysql 中是不可能的。但是,您可以在您的应用程序代码(php 等)中这样做,而不会有太多麻烦。 如果 prefixfqdn 形成 1 个唯一(主)键,您认为为什么需要 id 列?删除 id 解决了你整个无意义的工作,并尝试选择你已经拥有的东西。 什么是“SELECT INSERT”?能有什么意义? 我同意@TimBurch - 我可能会在应用层中通过 default 来处理这个问题;因为id 通常最好由数据库递增,所以无论如何你必须在插入后SELECT 才能得到它......尝试插入,然后在重复键失败(或不影响行,如果插入被写入那样)不要报告错误(可能),只需执行选择行,就好像什么都没发生一样。不过,对于这种设计,这里有多个问题。 @DanFromGermany - 拥有代理键​​允许更改与帐户关联的电子邮件地址(或者更容易,无论如何)。 StackExchange 可能会在后端使用它,因为我已经更改了与此帐户关联的电子邮件地址... 【参考方案1】:

如果表包含AUTO_INCREMENT 列和INSERT ... UPDATE 插入一行,LAST_INSERT_ID() 函数返回 AUTO_INCREMENT 值。如果该语句改为更新一行, LAST_INSERT_ID() 没有意义。但是,您可以解决此问题 通过使用LAST_INSERT_ID(expr)。假设 id 是AUTO_INCREMENT 柱子。要使 LAST_INSERT_ID() 对更新有意义,请插入行 如下:

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;

来自http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

【讨论】:

这之后你还是要执行SELECT(或者调用C API函数),当然,这只是意味着你可以使用LAST_INSERT_ID();鉴于他已经拥有唯一的密钥,因此不需要太多。应该指出的是,所提供的函数参数的值是基于连接的,线程安全也是如此。

以上是关于MySQL INSERT 与 ON DUPLICATE SELECT 可能吗?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL INSERT INTO / ON DUPLICATE KEY 与 SELECT 语句问题

MySQL多个INSERT与ODBC上的ON DUPLICATE KEY UPDATE问题

MySQL的replace into 与insert into on duplicate key update

MySQL的replace into 与insert into on duplicate key update

insert into ... on duplicate key update 与 replace 区别

Postgresql insert on conflict笔记