Bug #67535 | LAST_INSERT_ID() and INSERT IGNORE behavior | ||
---|---|---|---|
Submitted: | 9 Nov 2012 13:41 | Modified: | 20 Nov 2012 8:09 |
Reporter: | Jonas Reinhardt | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: DML | Severity: | S3 (Non-critical) |
Version: | 5.0.97, 5.1.67, 5.5.29, 5.7.0 | OS: | Any (MS Windows, Linux) |
Assigned to: | CPU Architecture: | Any |
[9 Nov 2012 13:41]
Jonas Reinhardt
[9 Nov 2012 14:33]
Valeriy Kravchuk
Same result with Oracle's 5.5.28 on Windows.
[9 Nov 2012 17:14]
Sveta Smirnova
Thank you for the report. Verified as described. I think this is documentation issue. Also earlier manual says: "The value of LAST_INSERT_ID() remains unchanged if no rows are successfully inserted." And for INSERT IGNORE it should say "If you use INSERT IGNORE and the row is ignored, the AUTO_INCREMENT counter is not incremented and LAST_INSERT_ID() returns previous incremented value, which reflects that no row was inserted. "
[20 Nov 2012 8:09]
Jonas Reinhardt
I'm not sure, but I think the LAST_INSERT_ID returned 0 before, in older versions. The procedure I found the behavior is a couple of years old. My implemented work-around is now: SET @@session.last_insert_id=0; INSERT IGNORE ... IF last_insert_id()=0 THEN ...
[1 Feb 2014 6:09]
Roman Agapkin
i can also confirm this on version 5.6.10 community/windows and i am also not sure if this is a documentation issue. i can't find another way of indication wether insert ignore inserted a row or not. with the described functionality, this would make it more comfortably in a stored procedure.
[3 Feb 2014 0:33]
Rick James
I expanded the INSERTs/SELECTs as seen below. Two things to note: ** ROW_COUNT() may be the 'right' way to determine if an INSERT took effect. (Caution: '2' can be returned by a single-row REPLACE; I don't know about UPDATE.) ** Notice how InnoDB, but not MyISAM and MEMORY, burns ids. mysql> INSERT IGNORE INTO test_myisam (nr) VALUES (9); mysql> SELECT LAST_INSERT_ID() as myisam1, ROW_COUNT(); +---------+-------------+ | myisam1 | ROW_COUNT() | +---------+-------------+ | 1000 | 1 | +---------+-------------+ mysql> INSERT IGNORE INTO test_myisam (nr) VALUES (9); mysql> SELECT LAST_INSERT_ID() as myisam2, ROW_COUNT(); +---------+-------------+ | myisam2 | ROW_COUNT() | +---------+-------------+ | 1000 | 0 | +---------+-------------+ mysql> INSERT IGNORE INTO test_myisam (nr) VALUES (99); mysql> SELECT LAST_INSERT_ID() as myisam3, ROW_COUNT(); +---------+-------------+ | myisam3 | ROW_COUNT() | +---------+-------------+ | 1001 | 1 | +---------+-------------+ mysql> mysql> INSERT IGNORE INTO test_innodb (nr) VALUES (9); mysql> SELECT LAST_INSERT_ID() as innodb1, ROW_COUNT(); +---------+-------------+ | innodb1 | ROW_COUNT() | +---------+-------------+ | 2000 | 1 | +---------+-------------+ mysql> INSERT IGNORE INTO test_innodb (nr) VALUES (9); mysql> SELECT LAST_INSERT_ID() as innodb2, ROW_COUNT(); +---------+-------------+ | innodb2 | ROW_COUNT() | +---------+-------------+ | 2000 | 0 | +---------+-------------+ mysql> INSERT IGNORE INTO test_innodb (nr) VALUES (99); mysql> SELECT LAST_INSERT_ID() as innodb3, ROW_COUNT(); +---------+-------------+ | innodb3 | ROW_COUNT() | +---------+-------------+ | 2002 | 1 | +---------+-------------+ 1 row in set (0.00 sec) mysql> mysql> INSERT IGNORE INTO test_heap (nr) VALUES (9); mysql> SELECT LAST_INSERT_ID() as heap1, ROW_COUNT(); +-------+-------------+ | heap1 | ROW_COUNT() | +-------+-------------+ | 3000 | 1 | +-------+-------------+ 1 row in set (0.00 sec) mysql> INSERT IGNORE INTO test_heap (nr) VALUES (9); mysql> SELECT LAST_INSERT_ID() as heap2, ROW_COUNT(); +-------+-------------+ | heap2 | ROW_COUNT() | +-------+-------------+ | 3000 | 0 | +-------+-------------+ 1 row in set (0.00 sec) mysql> INSERT IGNORE INTO test_heap (nr) VALUES (99); mysql> SELECT LAST_INSERT_ID() as heap3, ROW_COUNT(); +-------+-------------+ | heap3 | ROW_COUNT() | +-------+-------------+ | 3001 | 1 | +-------+-------------+ 1 row in set (0.00 sec)