20

I'm using the MySql Connector .net, and I need to get the insert id generated by the last query. Now, I assume the return value of MySqlHelper.ExecuteNonQuery should be the last insert id, but it just returns 1.

The code I'm using is:

int insertID = MySqlHelper.ExecuteNonQuery(Global.ConnectionString, 
"INSERT INTO test SET var = @var", paramArray);

However insertID is always 1. I tried creating a MySql connection and opening/closing manually which resulted in the same behaviour

Splatbang
  • 756
  • 1
  • 12
  • 29

6 Answers6

115

Just use LastInsertedId field

MySqlCommand dbcmd = _conn.CreateCommand();
dbcmd.CommandText = sqlCommandString;
dbcmd.ExecuteNonQuery();
long imageId = dbcmd.LastInsertedId;
Cioxideru
  • 1,472
  • 1
  • 11
  • 13
  • 3
    This is the right answer. Tested with [MySql/Connector](http://dev.mysql.com/downloads/connector/net/) 6.3.8 – caligari Apr 23 '14 at 11:26
  • This is a way to do it, **but not if you need to strictly use MySqlHelper.ExecuteNonQuery**. One of the reasons to use MySqlHelper is when you want the connector to manage the connection pool, and, as stated in the [docs](https://dev.mysql.com/doc/connector-net/en/connector-net-programming-connection-pooling.html), one approach is to use the api overloads that do not take a new MySqlConnection object as a parameter, rather, let the connector manage its creation itself. So this is not a solution for such cases (mine). – Veverke Jun 01 '17 at 09:32
  • Thank you so much man. We were getting tossed around on a cross-platform setup for a client who already had SQL server and wanted MySQL. They had scope_identity used a bit and I was able to use a DbCommand object casted to MySqlCommand on the MySql implementations and get the LastInsertedId object. One line fix for the same Scope_Identity stuff from SQL Server. Saved my ass man, thank you truly. – Matthew Young Nov 11 '19 at 16:26
5

1 is the no of records effected by the query here only one row is inserted so 1 returns

for getting id of the inserted row you must use scope_identity() in sqlserver and LAST_INSERT_ID() in MySql

Nighil
  • 4,099
  • 7
  • 30
  • 56
5

Try to use this query to get last inserted id -

SELECT LAST_INSERT_ID();

Then, run DbCommand.ExecuteReader method to get IDataReader -

command.CommandText = "SELECT LAST_INSERT_ID()";
IDataReader reader = command.ExecuteReader();

...and get information from the reader -

if (reader != null && reader.Read())
  long id = reader.GetInt64(0);

...do not forget to close the reader;-)

Devart
  • 119,203
  • 23
  • 166
  • 186
4

I had the same problem, and after some testing, I found out that the problem seem to be the connection method; you are using a connection string.

This is of course to make use of the automatic connection pool reuse, but in this case it gave me trouble.

The final solution for me is to create a new connection, execute the insert query, and then execute the last_insert_id(). On the same connection.

Without using the same connection, last_insert_id() might return anything, I don't know why, but guess it looses track of things as it can be different connections.

Example:

MySqlConnection connection = new MySqlConnection(ConnectionString);
connection.Open();

int res = MySqlHelper.ExecuteNonQuery(
    connection,
    "INSERT INTO games (col1,col2) VALUES (1,2);");

object ores = MySqlHelper.ExecuteScalar(
connection,
"SELECT LAST_INSERT_ID();");

if (ores != null)
{
  // Odd, I got ulong here.
  ulong qkwl = (ulong)ores;
  int Id = (int)qkwl;
}

I hope this helps someone!

Tornseglare
  • 963
  • 1
  • 11
  • 24
0

I know this is an old post, but I have been facing the same issue as Snorvarg. Using MySqlHelper, and using a connection string instead of a Connection object (to allow MySqlHelper to use connection pooling), SELECT LAST_INSERT_ID() would often give me the ID of the previous query that was executed, or other times it would return zero. I would then have to call SELECT LAST_INSERT_ID() a second time to get the correct ID.

My solution was to encapsulate everything between the query that's being executed, and the calling of SELECT LAST_INSERT_ID() in a TransactionScope. This forces MySqlHelper to stick to one connection instead of opening two separate connections.

So:

string sql = "INSERT INTO games (col1,col2) VALUES (1,2);");
string connectionString = "some connection string";

using (TransactionScope scope = new TransactionScope)
{
    int rowsAffected = MySqlHelper.ExecuteNonQuery(connectionString, sql);    
    object id = MySqlHelper.ExecuteScalar(connectionString, "SELECT LAST_INSERT_ID();");
    scope.Complete();
}
Fabricio Rodriguez
  • 3,769
  • 11
  • 48
  • 101
0

try below working solution in repository .

 string query = $"INSERT INTO `users`(`lastname`, `firstname`, `email`, `createdate`, `isdeleted`) " +
                $"VALUES ('{userEntity.LastName}','{userEntity.FirstName}','{userEntity.Email}','{userEntity.CreateDate}',{userEntity.IsDeleted});" +
                $"SELECT LAST_INSERT_ID();";
           var res= _db.ExecuteScalar(query);

            return (int)(UInt64)res;