使用Golang SQL驱动程序和UUID的MS SQL uniqueidentifier

9
我正在使用Go 1.6.2连接到SQL-Server DB。 我正在使用go-mssqldb驱动程序(github.com/denisenkom/go-mssqldb)与sql包配合使用。
我的问题是,我正在使用github.com/twinj/uuid软件包创建uuids(我也尝试了其他一些),它们可以正确插入,但在尝试将它们扫描出来时出现问题。
err := Database.QueryRow("SELECT Id FROM ...").Scan(&struct.Id)

它返回翻转了前半部分的Id。我在这个SO帖子(https://dba.stackexchange.com/questions/121869/sql-server-uniqueidentifier-guid-internal-representation)和其他一些文章/帖子中找到了解释。
然而,我无法找到任何特定于Go解决此问题的内容。我无法改变SQL Server存储guids的方式。UUID扫描实现有什么我错过的东西吗?我还没有看到改变读取方式的方法。我的最后选择将是编写自己的实现来交换位,但想知道是否有遗漏驱动程序、UUID包或其他库的可能性。

你能否将查询改为使用 "SELECT convert(Id as varchar(36)) FROM ..."? - Mark
@mark 我会尝试一下并告诉你! - KenWin0x539
抱歉,更正一下:convert(char(36), Id)cast(Id as char(36)) 数据类型转换 - Mark
如果您将其作为答案添加,我会标记它已回答。 - KenWin0x539
太好了!你能试试 cast(Id as binary(16)) 吗?这样可能更有效率。它也会给出正确的 UUID 吗? - Mark
2个回答

16
将Id转换为char类型后,返回的Id按照预期的字节顺序排列:
"SELECT cast(Id as char(36)) FROM ..."

将其转换为二进制后与直接查询 Id 的结果相同。

0F F1 4D 44 F4 72 49 59 9F C8 18 C2 DB 26 3C 3C  As inserted

44 4D F1 0F 72 F4 59 49 9F C8 18 C2 DB 26 3C 3C  Id (no cast)
44 4D F1 0F 72 F4 59 49 9F C8 18 C2 DB 26 3C 3C  cast(Id as binary(16))
0F F1 4D 44 F4 72 49 59 9F C8 18 C2 DB 26 3C 3C  cast(Id as char(36))

1
我使用了一个自定义类型来替换uuid.UUID,效果很好,这样我就能避免每次都要自定义SQL查询(感谢https://github.com/go-gorm/gorm/issues/5419#issuecomment-1412398444)。
import (
"database/sql/driver"
mssql "github.com/microsoft/go-mssqldb"
)

type Guid struct {
guid mssql.UniqueIdentifier
}

func (j *Guid) Scan(value interface{}) error {
return j.guid.Scan(value)
}

func (j Guid) Value() (driver.Value, error) {
return j.guid.Value()
}

func (j Guid) String() string {
return j.guid.String()
}

func (j Guid) MarshalText() ([]byte, error) {
return []byte(j.guid.String()), nil
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接