2016-12-29 33 views
2

在我的一个项目中,我不得不从数据库中获取最后一个插入的ID,这样我就可以将新插入的数据与存储器数据同步,而无需执行SELECT * FROM my_db;查询,即我正在执行SELECT * FROM my_db WHERE id=new_indexMySqlCommand.LastInsertedId是如何工作的?

现在,我知道我正在使用的MySQL支持查询select last_insert_id();,所以我想我只是执行该命令并执行它。但在深入研究C#(我用于项目的编程语言)后,我发现MySqlCommand有一个LastInsertedId字段。

现在让我感到困惑的是,我期望字段的获取者只是执行相同的select last_insert_id();查询,但是从MySQL查看日志时,我看不到任何这样的查询。

所以我的问题是,MySqlCommand.LastInsertedId如何知道当ID由MySQL服务器自动生成时,为我插入的元组分配了什么ID?

+0

您是否启用了记录**全部**在该服务器上执行的查询? – e4c5

+0

@ e4c5我执行了'SET GLOBAL general_log ='ON';'命令,所以是的。无论如何,我看到我有我的问题回答。无论如何感谢对这个主题的兴趣。 – ILA

回答

2

当UPDATE查询后,MySQL服务器响应客户端软件(在你的情况下它是Connector/Net)时,它发送so-called OK_Packet over the tcp (or socket) connection。该数据包包含last_insert_id值。

在服务器上,它可用于任何INSERT查询,而无需另一个查询,因此wire-protocol处理程序只是将它引入响应数据包。

客户端软件从数据包中提取该值并将其呈现给LastInsertedId属性上的应用程序软件。

3

如果MySQL成功执行客户端请求的查询,则MySQL会发送OK_Packet作为响应。

在OK_Packet的MySQL的有效载荷包括最后插入的ID(请参阅文档上面链接):

Type  | Name   | Description 
------------|----------------|----------------------------------- 
int<1>  | header   | [00] or [fe] the OK packet header 
int<lenenc> | affected_rows | affected rows 
int<lenenc> | last_insert_id | last insert-id 
... 

MySQL bug #65452表示LastInsertId方法读取出数据的分组的:

public int GetResult(ref int affectedRow, ref int insertedId) 
{ 
... 
insertedId = (int)packet.ReadFieldLength(); 
... 
} 

这表明LastInsertId从OK_Packet获取值。在服务器上不执行select last_insert_id()将此值填充到OK_packet中,这就是为什么在查询日志中没有看到任何此类查询的原因。

+0

非常感谢您的详细回复。你真的解释了我想知道的一切。我选择@O的唯一原因。琼斯接受的答案是因为他回答得更快,并说基本上是同样的事情。 – ILA