SELECT CONVERT(LAST_INSERT_ID(), SIGNED INTEGER);
MySqlCommand.ExecuteScalar()とMySqlDataReader.GetValue(int index)は、どちらも戻り値と
object
タイプを返します。そのLAST_INSERT_IDを明示的にSIGNED INTEGERに変換したので、
(int)cmd.ExecuteScalar()
や
(int)rdr.GetValue(0)
のようなものを使用してそのオブジェクトのボックス化を解除できると思いました。
ただし、キャストが無効であることを示すエラーが表示され続けます。デバッグ中に、返されるオブジェクトのタイプがINT64であることに気付きました。したがって、
(long)cmd.ExecuteScalar()
を使用して値をキャストすることで、オブジェクトのボックスを解除できます。
INT32ではなくINT64として返される理由を理解しようとしていますか?
ちなみに、自動インクリメント列のデータ型はSIGNED INTEGERです。
ここにテストケースがあります:
using (MySqlConnection con = new MySqlConnection(ConfigurationManager.ConnectionStrings["skimmel"].ConnectionString))
{
using (MySqlCommand cmd = new MySqlCommand(@"INSERT INTO test (Name) VALUES (@Name); SELECT CONVERT(LAST_INSERT_ID(), SIGNED INTEGER);", con))
{
var p = new MySqlParameter("@Name", MySqlDbType.String);
p.Value = "Test" + DateTime.Now.Ticks.ToString();
cmd.Parameters.Add(p);
con.Open();
object val = cmd.ExecuteScalar();
Type t = val.GetType();
long l = (long)val;
int i1 = Convert.ToInt32(val);
int i2 = (int)val; // <-- Error here!
}
}
一部のフォローアップテストを行ったところ、問題がLAST_INSERT_IDに限定されていないことがわかりました。
SELECT 1 AS ID
と
SELECT CONVERT(1, SIGNED INTEGER) As ID
も、コネクタを介して64ビット整数を返します。
ILSpyにMySql.Dataをロードして、何かを理解できるかどうかを確認しようとしています
Connector / Netのバグを投稿してフィードバックを得た後、ドキュメントに移動しました。整数型にキャストすると、CONVERTとCASTはどちらも64ビットの数値になります。彼らがCAST(1 As SMALLINT)、CAST(1 AS INT)、CAST(1 AS BIGINT)のようなことをしないのはなぜですか? MySQLサーバーからLONGLONG(64ビット)として返されるため、コネクタは32ビットの整数であることを認識しません。
私はまだLAST_INSERT_ID()がサーバーからLONGLONGを返す理由を理解しようとしています。