Clearing LAST_INSERT_ID() before inserting to tell if what's returned is from my insert
Reliably Detecting New Inserts with LAST_INSERT_ID() in MySQL

Learn how to confidently determine if a LAST_INSERT_ID() value in MySQL originates from your current INSERT statement, even when auto-increment values might be pre-existing.
When working with auto-incrementing primary keys in MySQL, the LAST_INSERT_ID() function is invaluable for retrieving the ID generated by the most recent INSERT statement. However, a common challenge arises when you need to distinguish between a newly generated ID and a pre-existing one, especially in scenarios where an INSERT ... ON DUPLICATE KEY UPDATE or similar construct might not actually insert a new row. This article explores a robust method to ensure the LAST_INSERT_ID() you retrieve is indeed from your current, successful INSERT operation.
Understanding LAST_INSERT_ID() Behavior
The LAST_INSERT_ID() function returns the first auto-increment value generated by the most recently executed INSERT statement for a connection. This is crucial: it's per-connection, meaning concurrent operations from other clients won't affect your session's LAST_INSERT_ID(). However, its behavior can be tricky. If an INSERT statement fails or doesn't generate a new auto-increment value (e.g., due to a UNIQUE constraint violation with INSERT IGNORE), LAST_INSERT_ID() will return 0 or the value from the previous successful INSERT within the same session. This ambiguity is what we aim to resolve.
flowchart TD
A[Start Transaction] --> B{Execute INSERT Statement}
B --> C{Was a new row inserted?}
C -->|Yes| D[Retrieve LAST_INSERT_ID()]
C -->|No (e.g., duplicate key)| E[LAST_INSERT_ID() remains unchanged or 0]
D --> F[Use the new ID]
E --> G[Handle no new ID]
F --> H[Commit/Rollback]
G --> HFlowchart illustrating LAST_INSERT_ID() behavior after an INSERT.
The Problem: Ambiguous Zero or Stale IDs
Consider a scenario where you perform an INSERT and then immediately check LAST_INSERT_ID(). If the INSERT didn't actually create a new row (e.g., INSERT IGNORE on a duplicate key), LAST_INSERT_ID() might return 0 or, more problematically, the ID from a previous INSERT in the same session. This can lead to incorrect assumptions about whether your current operation successfully added a new record. Simply checking if LAST_INSERT_ID() > 0 isn't sufficient because a previous INSERT might have left a non-zero value.
LAST_INSERT_ID() > 0 after an INSERT can be misleading if a previous INSERT in the same session was successful and the current one failed or didn't generate a new ID.The Solution: Clearing LAST_INSERT_ID() Before Insert
To definitively know if the LAST_INSERT_ID() returned is from your current INSERT statement, you can explicitly reset it to 0 immediately before executing the INSERT. This ensures that if the INSERT fails to generate a new auto-increment value, LAST_INSERT_ID() will remain 0, clearly indicating no new row was added by this specific operation. If a new row is inserted, LAST_INSERT_ID() will then hold the newly generated ID.
1. Step 1: Set LAST_INSERT_ID() to 0
Before your INSERT statement, execute SELECT LAST_INSERT_ID(0);. This explicitly sets the session's LAST_INSERT_ID() to 0.
2. Step 2: Execute Your INSERT Statement
Perform your INSERT operation as usual. This could be a simple INSERT, INSERT IGNORE, or INSERT ... ON DUPLICATE KEY UPDATE.
3. Step 3: Retrieve and Check LAST_INSERT_ID()
Immediately after the INSERT, retrieve the value using SELECT LAST_INSERT_ID();. If the value is greater than 0, a new row was successfully inserted by your current statement. If it's 0, no new row was inserted.
-- Example Table
CREATE TABLE `users` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(50) UNIQUE NOT NULL,
`email` VARCHAR(100)
);
-- Scenario 1: Successful Insert
SELECT LAST_INSERT_ID(0); -- Clear previous ID
INSERT INTO `users` (`username`, `email`) VALUES ('john_doe', 'john@example.com');
SELECT LAST_INSERT_ID(); -- Returns the new ID (e.g., 1)
-- Scenario 2: Duplicate Key (no new insert)
SELECT LAST_INSERT_ID(0); -- Clear previous ID
INSERT IGNORE INTO `users` (`username`, `email`) VALUES ('john_doe', 'john@example.com');
SELECT LAST_INSERT_ID(); -- Returns 0, indicating no new row was inserted by this statement
-- Scenario 3: Another successful insert
SELECT LAST_INSERT_ID(0); -- Clear previous ID
INSERT INTO `users` (`username`, `email`) VALUES ('jane_doe', 'jane@example.com');
SELECT LAST_INSERT_ID(); -- Returns the new ID (e.g., 2)
SQL examples demonstrating clearing LAST_INSERT_ID() before an insert.