mysql - 插入后忽略获取主键

Posted

技术标签:

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

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

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

SELECT LAST_INSERT_ID();

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

最好的方法是什么?

【问题讨论】:

试试看。它应该工作。如果没有,请告诉我们 看这个:***.com/questions/778534/… 不幸的是,它不起作用,尽管官方文档相反; INSERT IGNORE 后跟 LAST_INSERT_ID() 将返回最后插入的 ID(如果同一会话中没有插入,则返回 0)。参见示例:pastebin.com/KQaCQABR 【参考方案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?

【讨论】:

以上是关于mysql - 插入后忽略获取主键的主要内容,如果未能解决你的问题,请参考以下文章

sql解决主键冲突

插入忽略不会忽略

插入忽略 - 询问MySQL if语句是否被忽略

SSIS 2012 - 插入新行,忽略现有行

MySQL - 忽略插入错误:重复条目

将日期插入 MySQL 数据库时如何忽略时间戳