web-dev-qa-db-ja.com

MySql最終挿入ID、コネクタ.net

MySql Connector .netを使用していて、最後のクエリで生成された挿入IDを取得する必要があります。ここで、MySqlHelper.ExecuteNonQueryの戻り値は最後の挿入IDであると想定しますが、1を返すだけです。

私が使用しているコードは:

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

ただし、insertIDは常に1です。MySql接続を作成し、手動で開閉すると、同じ動作が発生しました

14
Splatbang

1はクエリの影響を受けるレコードの数ではなく、1行のみが挿入されるため、1が返されます

挿入された行のIDを取得するには、SQLサーバーではscope_identity()を、MySqlではLAST_INSERT_ID()を使用する必要があります

3
Nighil

LastInsertedIdフィールドを使用するだけ

MySqlCommand dbcmd = _conn.CreateCommand();
dbcmd.CommandText = sqlCommandString;
dbcmd.ExecuteNonQuery();
long imageId = dbcmd.LastInsertedId;
87
Cioxideru

同じ問題があり、いくつかのテストを行った結果、問題は接続方法のようであることがわかりました。接続文字列を使用しています。

これはもちろん自動接続プールの再利用を利用するためのものですが、この場合は問題が発生しました。

私の最終的な解決策は、新しい接続を作成し、挿入クエリを実行してから、last_insert_id()を実行することです。 same接続の場合。

同じ接続を使用しないと、last_insert_id()は何も返さない可能性があります。理由はわかりませんが、接続が異なる可能性があるため、追跡が失われると思います。

例:

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;
}

これが誰かに役立つことを願っています!

4
Snorvarg

このクエリを使用して、最後に挿入されたIDを取得してみてください-

SELECT LAST_INSERT_ID();

次に、DbCommand.ExecuteReaderメソッドを実行してIDataReaderを取得します-

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

...そして読者から情報を得る-

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

...リーダーを閉じることを忘れないでください;-)

3
Devart

これは古い投稿であることは知っていますが、Snorvargと同じ問題に直面しています。 MySqlHelperを使用し、接続オブジェクトの代わりに接続文字列を使用して(MySqlHelperが接続プールを使用できるようにするため)、SELECT LAST_INSERT_ID()は、以前に実行されたクエリのIDなどをしばしば提供しますゼロを返します。次に、正しいIDを取得するためにSELECT LAST_INSERT_ID()をもう一度呼び出す必要があります。

私の解決策は、実行されているクエリとSELECT LAST_INSERT_ID()の呼び出しの間のすべてをTransactionScopeでカプセル化することでした。これにより、MySqlHelperは2つの個別の接続を開くのではなく、1つの接続に固執します。

そう:

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();
}
0