go-mssqldb读取SQL Server uniqueidentifier类型Id返回错误值
问题原因
SQL Server的uniqueidentifier类型遵循Windows GUID混合字节序存储规则:前3个分段使用小端序存储,后2个分段使用大端序存储,和RFC 4122标准的UUID大端序存储规则不匹配,因此直接用标准UUID类型读取会出现前半段字节反转的问题。
解决方案
提供三种可直接落地的方案,按实现复杂度从低到高排列:
- 方案1:修改连接参数,让驱动直接返回正确的UUID字符串(推荐)
denisenkom/go-mssqldb驱动原生支持配置uniqueidentifiertype参数,设置为string后会自动处理字节序转换,直接返回符合预期的UUID字符串。
修改连接构造代码即可:
后续Scan时用string类型接收ID字段,再转成你使用的UUID类型即可:cnUrl:= &url.URL{ Scheme: driverName, Host: host, User: url.UserPassword(user, password), } // 新增下面一行配置参数 cnUrl.RawQuery = url.Values{"uniqueidentifiertype": {"string"}}.Encode() connString := cnUrl.String()var idStr string err := row.Scan(&idStr, &dbLogin.Login) parsedUUID, err := uuid.Parse(idStr) - 方案2:使用驱动自带的UniqueIdentifier类型
驱动原生提供了mssql.UniqueIdentifier类型,内置了字节序转换逻辑,直接用该类型接收字段即可:var mssqlUUID mssql.UniqueIdentifier err := row.Scan(&mssqlUUID, &dbLogin.Login) // 调用String()直接得到正确的UUID字符串 parsedUUID, err := uuid.Parse(mssqlUUID.String()) - 方案3:手动转换字节序
如果你不想修改现有逻辑,也可以将字段读取为[]byte后手动调整字节序:var idBytes []byte err := row.Scan(&idBytes, &dbLogin.Login) // 调整前三个分段的字节序 fixedBytes := []byte{ idBytes[3], idBytes[2], idBytes[1], idBytes[0], idBytes[5], idBytes[4], idBytes[7], idBytes[6], idBytes[8], idBytes[9], idBytes[10], idBytes[11], idBytes[12], idBytes[13], idBytes[14], idBytes[15], } parsedUUID, err := uuid.FromBytes(fixedBytes)
内容的提问来源于stack exchange,提问作者Fedir Katushonok
相关产品推荐
相关产品推荐

