当我使用时:
START TRANSACTION;
INSERT IGNORE INTO users (Name, ...) VALUES ('user1',..) ON DUPLICATE KEY UPDATE lastSeen=NOW();
SELECT LAST_INSERT_ID();
COMMIT;
当我从我的sql客户端运行此查询时,我按预期获得最后一个插入的ID。
但是如果用户已经存在怎么办?(table uniquness)。所以没有创建新的id。但是现在当我从我的SQL客户端运行相同的查询时,仍然按预期得到id
。
但是!当我从C#
代码运行它并使用mysql.reader
查询我收到的0
结果时。为什么???
如果我使用SELECT LAST_INSERT_ID()
代替SELECT id FROM users ORDER BY id DESC LIMIT 1
,我会再次获得正确的ID。
修改<!/强>
这与建议的主题不重复。在那个主题中答案说自动递增不是主键,这不是我的情况!另外,当我使用mysql客户端时,它确实返回正确的id!只有当我从我的c#代码中运行它时才会出现问题!
我的C#代码:
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;
}
}
答案 0 :(得分:1)
我找到了一个解决方法,简单CASE
子句完成工作:
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;
现在,如果用户存在,我们只需查询id,如果它不存在,LAST_INSERT_ID()
将为我们提供正确的ID
答案 1 :(得分:1)
从我在那里阅读https://stackoverflow.com/a/15057619/4421474
您的代码可以转换为:
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;
}
抱歉,我不是c#expert,因此可能会破坏某些语法。
答案 2 :(得分:0)
我想这个答案:
这个问题只需50美分,我只是注意到如果你的表没有将AUTO_INCREMENT设置为索引,你就不会得到大于0的LAST_INSERT_ID
我在这里找到的MySQL: LAST_INSERT_ID() returns 0是好的。