MySQL中char(36)被認為是GUID導致的BUG及解決方案


有時候在使用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) 就可以了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM