有時候在使用Toad或在程序中,偶爾會遇到如下的錯誤:
System.FormatException GUID 應包含帶 4 個短划線的 32 位數(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。 Stack Trace: 在 System.Guid..ctor(String g) 在 MySql.Data.Types.MySqlGuid.MySql.Data.Types.IMySqlValue.ReadValue(MySqlPacket packet, Int64 length, Boolean nullVal) 在 MySql.Data.MySqlClient.NativeDriver.ReadColumnValue(Int32 index, MySqlField field, IMySqlValue valObject) 在 MySql.Data.MySqlClient.ResultSet.ReadColumnData(Boolean outputParms) 在 MySql.Data.MySqlClient.ResultSet.NextRow(CommandBehavior behavior) 在 MySql.Data.MySqlClient.MySqlDataReader.Read() 在 Quest.Toad.Db.ToadDataAdapter.InternalReadBackground() |
原因是如果一個字段定義為 CHAR(36), 則MySQL官方的連接器會將其當成 GUID 類型,有些情況下會要求你輸入(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)形式的字符串,否則會報錯。實際上,有時候 某個字段碰巧設為可CHAR(36), 但是我們的本意並非當它是GUID。
(例如使用 MySqlDataAdapter 的 Fill 方法填充 DataTable時,就會拋出 Exception。可以使用連接器安裝后所附帶的 TableEditor 進行觀察,重復出這個Bug)
今天特意追蹤了一個MySql.Data中的代碼:發現MySqlCommand在Prepare的時候會調用Driver的PrepareStatement方法,會初始化ResultSet,會調用MySqlField.SetTypeAndFlags,其中有代碼如下:
if (((this.Type == MySqlDbType.String) && (this.CharacterLength == 0x24)) && !this.driver.Settings.OldGuids) { this.mySqlDbType = MySqlDbType.Guid; }
原因查明,解決方法是:將這個字段修改為 VARCHAR(36) 或者 CHAR(40),總之,不是 CHAR(36) 就可以了。