【问题标题】:mysql - after insert ignore get primary keymysql - 插入后忽略获取主键
【发布时间】:2011-09-11 14:16:13
【问题描述】:

我正在使用 Python 在 mysql insert ignore into........ 中运行查询

运行查询后,我想知道该行的主键。我知道有查询

SELECT LAST_INSERT_ID();

但我不确定它是否适用于插入忽略

最好的方法是什么?

【问题讨论】:

  • 试试看。它应该工作。如果没有,请告诉我们
  • 不幸的是,它不起作用,尽管官方文档相反; INSERT IGNORE 后跟 LAST_INSERT_ID() 将返回最后插入的 ID(如果同一会话中没有插入,则返回 0)。参见示例:pastebin.com/KQaCQABR

标签: mysql


【解决方案1】:

The documentation for LAST_INSERT_ID() 说:

如果您使用 INSERT IGNORE 并且该行被忽略,则 AUTO_INCREMENT 计数器不会增加并且 LAST_INSERT_ID() 返回 0,这表明没有插入任何行。

知道了这一点,您就可以将其变成一个多步骤的过程:

  • 插入忽略
  • 如果 LAST_INSERT_ID(),则完成(插入新行)
  • else SELECT your_primary key FROM yourtable WHERE(您插入的数据的唯一约束)

以美国各州为例:

id  | abbrev | other_data
 1  | AL     | ...
 2  | AK     |

UNIQUE KEY abbr (abbrev)

现在,插入一个新行:

INSERT IGNORE INTO `states` (`abbrev`,`other_data`) VALUES ('AZ','foo bar');
> OK
SELECT LAST_INSERT_ID();
> "3"
// we have the ID, we're done

插入将被忽略的行:

INSERT IGNORE INTO `states` (`abbrev`,`other_data`) VALUES ('AK','duplicate!');
> OK
SELECT LAST_INSERT_ID();
> "0"
// oops, it already exists!
SELECT id FROM `states` WHERE `abbrev` = 'AK'; // our UNIQUE constraint here
> "2"
// there we go!

或者,有一种可能的解决方法可以一步完成 - 使用 REPLACE INTO 而不是 INSERT IGNORE INTO - the syntax is very similar。但请注意,这种方法存在副作用 - 这些对您可能很重要,也可能不重要:

  • REPLACE 删除+重新创建行
    • 所以 DELETE 触发器是,嗯,触发了
    • 此外,即使行存在,主 ID 也会递增
    • INSERT IGNORE 保留旧行数据,REPLACE 用新行数据替换它

【讨论】:

  • 警告:如果之前有一个类似的插入,其 DID 有一个 last_insert_id(),那么将返回该值,这将破坏您的算法。换句话说,如果你 insert ignore 并且发生了实际插入(比如值 3),然后再次 insert ignore 没有变化,last_insert_id() 将返回 3。
  • @JamiesonBecker:这与文档所说的(以及我看到这段代码的作用)直接矛盾。在您的示例中,LAST_INSERT_ID() 将根据文档返回0。我能找到的唯一相关部分是If the previous statement returned an error, the value of LAST_INSERT_ID() is undefined. For transactional tables, if the statement is rolled back due to an error, the value of LAST_INSERT_ID() is left undefined.,这与您所声称的非常不同。请为您的主张提供证据。
  • 对不起,@Piskvor,undefined 表示未定义,而不是 0,但您是对的,这就是文档所说的。该文档是明确的,但显然是错误的,至少对于 MySQL 5.5.41 而言。最后插入的 ID 在忽略插入时不会被清除或重置为 0,但会返回先前的值。证据,自己试试:pastebin.com/KQaCQABR
  • 我知道“未定义”的意思是“任何东西都可能在那里,包括玛蒂尔达阿姨”;)您粘贴的内容看起来像一个错误。
  • 服务器或文档中的错误?我倾向于同意两者:)
【解决方案2】:

尝试使用 ON DUPLICATE KEY 而不是 INSERT IGNORE,也许这对你有用:

INSERT INTO your_table (`id`,`val`) VALUES(1,'Foo') ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(`id`);

SELECT LAST_INSERT_ID();

另见相关问题:MySQL ON DUPLICATE KEY - last insert id?

【讨论】:

    猜你喜欢
    • 2016-06-15
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多