是否可以将Sqlite Blob列转换为十六进制字符串(GUID)?

是否可以将Sqlite Blob列转换为十六进制字符串(GUID)?,sql,sqlite,blob,guid,Sql,Sqlite,Blob,Guid,我有一个SQLite表,其中有一列将GUID存储为字节数组 我正在尝试从SQL查询中获取Guid字符串。 到目前为止,我已经尝试: 从[MyTable]中选择BlobGuidColumn 但这将返回一个blob列 是否可以从SQL查询返回十六进制字符串?使用此问题中的信息: 这个问题: 我得到了答案: SELECT substr(hex(BlobGuidColumn), 1, 8) || '-' || substr(hex(BlobGuidColumn), 9, 4) || '-' || sub

我有一个SQLite表,其中有一列将GUID存储为字节数组

我正在尝试从SQL查询中获取Guid字符串。 到目前为止,我已经尝试:

从[MyTable]中选择BlobGuidColumn

但这将返回一个blob列


是否可以从SQL查询返回十六进制字符串?

使用此问题中的信息: 这个问题:

我得到了答案:

SELECT substr(hex(BlobGuidColumn), 1, 8) || '-' || substr(hex(BlobGuidColumn), 9, 4) || '-' || substr(hex(BlobGuidColumn), 13, 4) || '-' || substr(hex(BlobGuidColumn), 17, 4) || '-' || substr(hex(BlobGuidColumn), 21, 12) FROM [MyTable]

接受的答案存在一些问题,但最重要的是它并不总是产生正确的结果。如果目标只是将128位从二进制映射到GUID(如8-4-4-4-12表示),那么就可以了。但是,如果您确实希望某些内容的计算结果为相同的GUID,则不会这样做,因为不考虑基础数据的endianness

以下面的guid为例:

BC7CAE8C-E4D7-49CA-86E4-5FD540106CC0

表示为一个字节数组,您不必

BC-7C-AE-8C-E4-D7-49-CA-86-E4-5F-D5-40-10-6C-C0

答案是,由于GUID/UUID的内部表示取决于所讨论的UUID的变量,因此其字节顺序是相关的。变体1 UUID严格按照网络字节顺序为小端,而变体2 UUID在各个方面都是相同的,只是一半的分组以大端字节顺序存储在内存或数据库的磁盘上,而另一半则以网络字节顺序存储

我写了一篇关于这个问题的长篇文章,深入探讨了UUID/GUID的历史以及两个变体之间的差异,并提供了将UUID从二进制转换为文本的说明:

根据所讨论的变量,您可以直接使用SQL十六进制函数:

或者,如果源数据来自Microsoft world,例如COM/WIN32/.NET应用程序,则需要使用这种复杂得多的方法,这种方法会为每个分组考虑适当的字节顺序:

SELECT
substr(hguid, 7, 2) || substr(hguid, 5, 2) || substr(hguid, 3, 2) || substr(hguid, 1, 2) || '-'
|| substr(hguid, 11, 2) || substr(hguid, 9, 2) || '-'
|| substr(hguid, 15, 2) || substr(hguid, 13, 2) || '-'
|| substr(hguid, 17, 4) || '-'
|| substr(hguid, 21, 12)

AS guid

FROM (SELECT hex(guid) AS hguid FROM messages)
在这里,guid列在最后一行仅转换为十六进制一次,以避免对每个字节重复转换的开销

事实上,我不清楚微软SQL Server是否像OP的特定场景一样,以网络字节顺序在磁盘上存储GUID,还是以部分big-endian形式存储GUID,尽管我倾向于认为是后者,因为微软技术在其他任何地方都是如此,这不是一个普遍的规则,但总的来说,guid意味着Little Endian,而uuid意味着Big——更多信息请参见


提示:如果结果以零开头,则说明您做得不对。给定UUIDv1/UUIDv2时间戳中第一组的源,许多分辨率有限的源在第一组十六进制数字的末尾有零。但如果转换不正确,该组将在开始时结束:这是一个确定的迹象,表明您需要在特定情况下使用替代答案。

我发布了一个考虑字节顺序的替代答案。我只是想让您知道,根据二进制数据的来源和转换原因,如果它最初是由Windows软件创建的GUID,则可能无法获得所需的结果。
SELECT
substr(hguid, 7, 2) || substr(hguid, 5, 2) || substr(hguid, 3, 2) || substr(hguid, 1, 2) || '-'
|| substr(hguid, 11, 2) || substr(hguid, 9, 2) || '-'
|| substr(hguid, 15, 2) || substr(hguid, 13, 2) || '-'
|| substr(hguid, 17, 4) || '-'
|| substr(hguid, 21, 12)

AS guid

FROM (SELECT hex(guid) AS hguid FROM messages)