2016-12-29 35 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