以下是查询:
string query = @"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint)
VALUES (UUID(), @UId, @LogInTime, @MIp, @MFingerPrint);
";
现在我需要最后一个插入的id,这是MySQL生成的UUID。据我所知,UUID没有select_last_insert_id()函数!我读了php,你可以先将UUID()函数赋给变量,然后返回该值。但是如何在C#中实现呢?
这样的东西,但不完全是:
string query = @"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint)
VALUES (@UUID = SELECT UUID(), @UId, @LogInTime, @MIp, @MFingerPrint);
"; //how to do this here?
以下是我的更多代码:
string query = @"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint)
VALUES (@UUID = SELECT UUID(), @UId, @LogInTime, @MIp, @MFingerPrint);
";
try
{
if (_conn.State != ConnectionState.Open)
_conn.Open();
MySqlCommand cmd = new MySqlCommand(query, _conn);
cmd.Parameters.AddWithValue("@UId", Utility.usr.Id);
cmd.Parameters.AddWithValue("@LogInTime", DateTime.Now);
cmd.Parameters.AddWithValue("@MIp", GetMachineIP());
cmd.Parameters.AddWithValue("@MFingerPrint", GetHardwareFingerPrint());
var s= Convert.ToString(cmd.ExecuteScalar()); //this returns an empty string :(
//I need to get it to any .NET data type, string, or Guid or byte[] or anything.
但是我需要s
的这种数据类型在这样的查询中的另一个WHERE
子句中使用:
string query = @"UPDATE session SET logout_time = @LogOutTime
WHERE user_id = @UId AND PK_Id = @SessionId";
try
{
if (_conn.State != ConnectionState.Open)
_conn.Open();
MySqlCommand cmd = new MySqlCommand(query, _conn);
cmd.Parameters.AddWithValue("@UId", Utility.usr.Id);
cmd.Parameters.AddWithValue("@SessionId", s);
cmd.Parameters.AddWithValue("@LogOutTime", DateTime.Now);
cmd.ExecuteScalar();
此处@"SessionId"
是同一个表中的UUID字段。基本上,我如何在C#中获取MySQL varbinary字段,以便通过在另一个查询中指定WHERE来使用该类型进行更新?
在MySQL表中,UUID字段是varbinary (我希望看到一些解决方案不是另一个php链接,或者不要求我在数据库中切换到char数据类型)。)。< / p>
编辑:这里的问题是我们已经将MySQL生成的大量UUID添加到表中,所以我有点担心将MySQL UUID更改为.NET Guid。如果那是唯一的解决方法,我会考虑的。只是这是我们第一次需要插入的UUID值,以便我可以在另一个查询中更新另一个时间点。
一个子问题:.NET Guid与MySQL UUID完全相同吗?
答案 0 :(得分:2)
您可以使用Guid
类型,它是UUID的MS实现。您应该知道,在将数据插入数据库时,如果MySQL驱动程序不熟悉处理Guid,您可能需要将Guid转换为ByteArray。有关此示例,请参阅Store GUID in MySQL from C#。
答案 1 :(得分:1)
我认为您可以继续执行早期的实施,而不必依赖MS Guid,但我担心我太迟了:)
string query = @"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint)
VALUES (UUID(), @UId, @LogInTime, @MIp, @MFingerPrint);
SELECT PK_Id FROM session WHERE login_time=@LogInTime AND machine_fingerprint=@MFingerPrint; //or something similar which gives you the exact same id - UUID
";
try
{
if (_conn.State != ConnectionState.Open)
_conn.Open();
MySqlCommand cmd = new MySqlCommand(query, _conn);
cmd.Parameters.AddWithValue("@UId", Utility.usr.Id);
cmd.Parameters.AddWithValue("@LogInTime", DateTime.Now);
cmd.Parameters.AddWithValue("@MIp", GetMachineIP());
cmd.Parameters.AddWithValue("@MFingerPrint", GetHardwareFingerPrint());
MySqlDataReader r = cmd.ExecuteReader();
if (r.Read()) //ensure if it is read only once, else modify your `WHERE` clause accordingly
{
var s = (Guid)r[0];
}
//or even (Guid)cmd.ExecuteScalar() would work
现在您可以在此更新中查询:
string query = @"UPDATE session SET logout_time = @LogOutTime
WHERE user_id = @UId AND PK_Id = @SessionId";
try
{
if (_conn.State != ConnectionState.Open)
_conn.Open();
MySqlCommand cmd = new MySqlCommand(query, _conn);
cmd.Parameters.AddWithValue("@UId", Utility.usr.Id);
cmd.Parameters.AddWithValue("@SessionId", s.ToByteArray());
cmd.Parameters.AddWithValue("@LogOutTime", DateTime.Now);
cmd.ExecuteNonQuery();
注意:在查询之前,我已将Guid变量s
转换为字节数组。这在WHERE
子句中非常重要,无论是查询中的UPDATE
还是SELECT
语句。我会请你从varbinary转到MySQL表中的二进制字段。
编辑:如果您的表格会大幅增长,那么插入和选择是一个坏主意,因为SELECT
查询是另一个正在运行的查询。在那种情况下@ PinnyM的选择更好。我真的不认为MySQL或任何其他数据库会有一种默认的方式来回馈“自定义”插入的ID,这些不是数据库生成的。所以简而言之,我建议你不要这样做..
Edit2 :有关将二进制值转换为.NET数据类型的信息,请参阅此answer。有时,根据MySQL .NET连接器版本,转换不起作用..
答案 2 :(得分:-1)
您也可以使用sproc中的out参数完成此操作。见NerfAnvil的回复:
How to get OUT parameter from MySQL stored procedure是一个几乎确切的例子。
cmd.Parameters [“outnextnoteid”]。Direction = ParameterDirection.Output;
...
nextNoteId =(int)cmd.Parameters [“outnextnoteid”]。值;