简体   繁体   中英

Get last inserted Id returns 0 if the row already exists

When I use:

START TRANSACTION;
INSERT IGNORE INTO users (Name, ...) VALUES ('user1',..) ON DUPLICATE KEY UPDATE lastSeen=NOW();
SELECT LAST_INSERT_ID();
COMMIT;

When i run this query from my sql client I get the last inserted id as expected.

But what if the user already exists?(table uniquness). So no new id is created. But now when I run the same query from my sql client still i get the id as expected.

But! when I run it from my C# code and use mysql.reader to query the result I receive 0 . Why is that??

If instead of SELECT LAST_INSERT_ID() I use SELECT id FROM users ORDER BY id DESC LIMIT 1 I get the right id again.

EDIT!

This is not a duplicate of the suggested topic. In that topic the answer says that the auto-incremented is not the primary key, thats not my case! also as I mark it does return the right id when i use the mysql client! The problem occures only when I run it from my c# code!

My C# code:

using (var conn = new MySqlConnection(connString))
{
    try
    {
        conn.Open();
        var command = conn.CreateCommand();
        command.CommandText = strSQL;
        MySqlDataReader reader;
        string result = "";
        try
        {
            reader = command.ExecuteReader();

            if (reader.Read())
                result = reader[0].ToString();
        }
        catch (Exception ex)
        {
            throw new MySqlException("SQL Error: " + ex.ToString());
        }
        reader.Close();
        return result;
    }
}

I have found a work around, simple CASE clause does the job:

START TRANSACTION;
INSERT IGNORE INTO users (Name, ...) VALUES ('user1',..) ON DUPLICATE KEY UPDATE lastSeen=NOW();
SELECT CASE WHEN LAST_INSERT_ID()=0 THEN (SELECT id FROM users WHERE Name = 'user1') ELSE LAST_INSERT_ID() END;
COMMIT;

Now in case the user exists, we simply query the id, If it doest not exists, the LAST_INSERT_ID() will give us the right id

From what I read there https://stackoverflow.com/a/15057619/4421474

Your code could be transformed to:

using (var conn = new MySqlConnection(connString))
{
   conn.Open();
   var command = conn.CreateCommand();
   command.CommandText = strSQL; <--  just insert part like "START ... INSERT ... COMMIT;"
   command.ExecuteNonQuery();
   string result = command.LastInsertedId;
   return result;
}

Sorry I am not c# expert so some syntax could be broken.

I guess this answer:

Just my 50 cents for this issue, I simply noticed that you won't get a LAST_INSERT_ID greater than 0 if your table has no AUTO_INCREMENT set to an index

that i found here MySQL: LAST_INSERT_ID() returns 0 is the good one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM