#light #r @"D:\Program Files\MySQL\MySQL Connector Net 5.2.5\Binaries\.NET 2.0\MySql.Data.dll" open System open System.Data open MySql.Data.MySqlClient
let conn = let builder = MySqlConnectionStringBuilder(CharacterSet = "utf8", Server = "localhost", UserID = "root", Password = "erp", Database = "erp") let conn = new MySqlConnection(builder.ConnectionString) conn.Open() conn let cmd = conn.CreateCommand()
cmd.CommandText <- " DROP TABLE IF EXISTS `TestGuid`; CREATE TABLE IF NOT EXISTS `TestGuid` (`ID` BINARY(16)) ENGINE = InnoDB; INSERT INTO `TestGuid` VALUES (0x012345670123012301230123456789ab); INSERT INTO `TestGuid` VALUES (?_ID);" let guid = Guid("12345678-1234-1234-1234-123456789abc")
cmd.Parameters.AddWithValue("_ID", guid.ToByteArray()) cmd.ExecuteNonQuery() cmd.CommandText <- " SELECT * FROM `TestGuid`" let reader = cmd.ExecuteReader() while reader.Read() do for i in0 .. reader.FieldCount - 1do print_any (reader.GetValue i) printfn "" Console.ReadKey()
上面这段代码只是简单的创建一个名为 TestGuid 的表, 只有的一个名为 ID 的 BINARY(16) 列.
SELECTHEX(ID) FROM TestGuid HEX(ID) '012345670123012301230123456789AB' '78563412341234121234123456789ABC'
天~ 这次是第二个反了.
冷静的想一想, 看来 MySql Server 是没有问题的, 问题出在 MySQL Connector Net 上面. 它在写入数据的时候搞错了二进制的高位与低位, 在读取的时候同样又搞错了一次, 错上加错, 结果似乎是对了, 只不过这个问题在其他系统中是不存在的, 换句话说, 这个问题带来的是跨系统之间数据不兼容.
没办法, 只能判断一下数据类型和操作系统版本, 暂时的规避一下吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// 先给 List 扩展一个切片方法, 以便支持 lst.[1 .. 3] 这样的操作 typeMicrosoft.FSharp.Collections.List<'a> with member t.GetSlice(n1, n2) = let l = t.Length - 1 let n1 = match n1 with Some x -> max x 0 | _ -> 0 let n2 = match n2 with Some x -> min x l | _ -> l [ for i in n1 .. n2 -> List.nth t i ] /// 修正 MySql 不能识别 Windows7 Guid 的问题 let repairWin7Guid (x :obj) = match x with | :? Guid as g -> if Environment.OSVersion.Version.Major = 6 && Environment.OSVersion.Version.Minor >= 1then let w = g.ToByteArray() |> Array.to_list let r = w.[3] :: w.[2] :: w.[1] :: w.[0] :: w.[5] :: w.[4] :: w.[7] :: w.[6] :: w.[8 ..] |> Array.of_list Guid(r) |> box else x | _ -> x