2012-01-19 179 views
2
SELECT CONVERT(LAST_INSERT_ID(), SIGNED INTEGER); 

MySqlCommand.ExecuteScalar()和MySqlDataReader.GetValue(INT指數)都返回並object類型。我假定,因爲我明確地將該LAST_INSERT_ID轉換爲SIGNED INTEGER,我可以使用類似(int)cmd.ExecuteScalar()(int)rdr.GetValue(0)的方式取消裝箱。C#MySqlConnector 6.4.4 LAST_INSERT_ID()作爲INT64?

但是,我不斷收到一個錯誤,指出演員表無效。在調試時,我注意到返回的對象的類型是INT64。因此,我可以通過使用(long)cmd.ExecuteScalar()來鑄造值來取消裝箱。

我只是想明白爲什麼它會回來作爲INT64而不是INT32?

順便說一句,我的自動增量列的數據類型是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 IDSELECT CONVERT(1, SIGNED INTEGER) As ID也通過連接器返回一個64位int。去嘗試看看我能否通過加載MySql.Data來計算出任何數據ILSpy

+0

什麼大小是生成此ID的基礎密鑰字段?如果實際的關鍵字段是64位,則last_insert_id()無法返回32位整型,而不截斷/破壞關鍵字。 –

+0

數據類型是一個有符號整數(不爲NULL) – Sam

回答

2

在發佈連接器/網絡錯誤並獲得反饋後,我被引導到文檔。轉換爲整數類型時,CONVERT和CAST都會生成64位數字。不知道他們爲什麼不只是做CAST(1作爲SMALLINT),CAST(1 AS INT),CAST(1 AS BIGINT)之類的東西,但他們沒有。由於它是從LONGLONG(64位)從MySQL服務器返回的,因此連接器不知道它應該是32位int。

我仍然試圖找出LAST_INSERT_ID()從服務器返回LONGLONG的原因。

0

可能是因爲當返回的值不是太大時,Convert.ToInt32()可以進行轉換(即該值將適合在一個32位整數)。雖然演員正在告訴編譯器,你認爲val是一個32位的值,但事實並非如此。

+0

我的數據庫類型是SIGNED INT,它應該是Int32。我在SQL中顯式轉換爲SIGNED INT。我知道ExecuteScalar給我一個BIGINT(Int64)。我想知道的是爲什麼MySqlConnector繼續爲我提供val作爲64位值而不是32位值。 – Sam

+0

是的,我明白你的意思 - 這很奇怪。如果您在返回之前沒有明確地投射它,會發生什麼? – Rikalous

+0

同樣的事情,這就是爲什麼我試着演員。 – Sam