【问题标题】:Retrieving an autoincrement value after INSERT duplicate key在插入重复键后检索自动增量值
【发布时间】:2017-09-24 11:16:06
【问题描述】:

我有一个 mySQL 5.7 myISAM 表 T:

Col  Key    Other
A    PRI   
B           autoincrement
C

我要执行以下操作: 给定值 x 和 y

  • 如果已经存在 A=x 的行,请将 B 还给我
  • 否则,在 A=x 和 C=y 的位置插入一行,然后返回 B

这样做的最简单方法似乎是

SELECT B FROM T WHERE A=x;
if the row doesn't exist,
INSERT INTO T SET A=x, C=y;
SELECT LAST_INSERT_ID();

但是,这是非原子的,这意味着我需要实现某种锁定。

我希望我可以使用

INSERT IGNORE INTO T SET A=x, C=y;
SELECT LAST_INSERT_ID();

但是当重复键上的 INSERT 被忽略时,LAST_INSERT_ID() 不会返回 B。

有没有一种简单的方法可以原子地完成此操作,无需锁定?

【问题讨论】:

  • 您是否正在处理表中已经存在的数据?插入忽略只是插入带有主键的记录,如果工作表中存在主键则跳过。
  • @reds - 我希望即使在这种情况下它也能返回自动增量字段。但仔细想想,这似乎需要访问数据行,IGNORE 允许我们绕过。
  • 停止使用 MyISAM;切换到 InnoDB。

标签: mysql sql-insert auto-increment myisam last-insert-id


【解决方案1】:

请参阅 IODKU 的 UPDATE 部分中如何使用 id=LAST_INSERT_ID(id) 的示例。 https://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html

【讨论】:

    【解决方案2】:

    我认为LAST_INSERT_ID() 没有办法做到这一点,因为只有在实际插入某些内容并分配了新 ID 时才会设置。您必须选择刚刚插入的密钥:

    INSERT IGNORE INTO T SET a=x, C=y;
    SELECT B FROM T WHERE a = x;
    

    【讨论】:

    • 是的。我在这里猜测,但似乎 mySQL 会首先查询其主键索引并发现重复键违规,而不会获取自动增量值所在的数据行。
    • 它们是两个独立的查询。当它发现INSERT 中的重复项时,它什么也不做,然后SELECTb 返回该行的值。
    • 我不清楚:我同意您的解决方案,并且我在推测为什么我最初的想法(即使 INSERT 发现重复项,LAST_INSERT_ID() 也可能有效)行不通。对不起!
    【解决方案3】:
    select max(id) from T
    

    这个选择表的最后一个id

    【讨论】:

    • 当有多个线程运行时,这不能保证有效。
    猜你喜欢
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 2011-08-16
    相关资源
    最近更新 更多