SQL Server中C# Guid.ToByteArray()的等效实现方法问询
SQL Server实现与C# Guid.ToByteArray()等效的uniqueidentifier转varbinary方法
问题背景
C#中Guid.ToByteArray()方法的字节输出采用混合字节序:前3个字段(uint、ushort、ushort)按小端顺序输出,剩余8字节按原顺序输出,具体实现逻辑如下:
public byte[] ToByteArray() { return new byte[16] { (byte)_a, // _a为Guid前4字节的uint值,取低字节 (byte)(_a >> 8), // _a右移8位,取下一字节 (byte)(_a >> 16), // _a右移16位 (byte)(_a >> 24), // _a右移24位,取高字节 (byte)_b, // _b为Guid第5-6字节的ushort值,取低字节 (byte)(_b >> 8), // _b右移8位,取高字节 (byte)_c, // _c为Guid第7-8字节的ushort值,取低字节 (byte)(_c >> 8), // _c右移8位,取高字节 _d, _e, _f, _g, _h, _i, _j, _k // 剩余8字节按原顺序输出 }; }
而SQL Server直接通过CAST/CONVERT将uniqueidentifier转成varbinary时,是按Guid字符串的十六进制顺序(大端)输出,与C#的结果不一致。需要实现等效逻辑,将指定Guid转换为与C#代码输出相同的varbinary。
实现方案
1. 直接表达式转换
针对给定的Guid字符串,可通过拆分各段并反转前3段的字节序来拼接目标结果:
DECLARE @guid NVARCHAR(36) = 'FFFA9208-0391-4924-947F-C0556198D2FC' SELECT -- 反转前4字节(Guid第一部分) CONVERT(VARBINARY(4), REVERSE(CONVERT(VARBINARY(4), LEFT(@guid, 8), 2))) + -- 反转接下来2字节(Guid第二部分) CONVERT(VARBINARY(2), REVERSE(CONVERT(VARBINARY(2), SUBSTRING(@guid, 10, 4), 2))) + -- 反转接下来2字节(Guid第三部分) CONVERT(VARBINARY(2), REVERSE(CONVERT(VARBINARY(2), SUBSTRING(@guid, 15, 4), 2))) + -- 直接取接下来2字节(Guid第四部分) CONVERT(VARBINARY(2), SUBSTRING(@guid, 20, 4), 2) + -- 直接取最后6字节(Guid第五部分) CONVERT(VARBINARY(6), SUBSTRING(@guid, 25, 12), 2) AS CSharpStyleGuidBytes
2. 封装为标量函数
如果需要重复使用,可封装成自定义函数:
CREATE FUNCTION dbo.GuidToCSharpByteArray(@guid UNIQUEIDENTIFIER) RETURNS VARBINARY(16) AS BEGIN DECLARE @guidStr NVARCHAR(36) = CONVERT(NVARCHAR(36), @guid) RETURN CONVERT(VARBINARY(4), REVERSE(CONVERT(VARBINARY(4), LEFT(@guidStr, 8), 2))) + CONVERT(VARBINARY(2), REVERSE(CONVERT(VARBINARY(2), SUBSTRING(@guidStr, 10, 4), 2))) + CONVERT(VARBINARY(2), REVERSE(CONVERT(VARBINARY(2), SUBSTRING(@guidStr, 15, 4), 2))) + CONVERT(VARBINARY(2), SUBSTRING(@guidStr, 20, 4), 2) + CONVERT(VARBINARY(6), SUBSTRING(@guidStr, 25, 12), 2) END GO
使用方式:
SELECT dbo.GuidToCSharpByteArray('FFFA9208-0391-4924-947F-C0556198D2FC')
结果验证
上述代码输出的varbinary值为0x0892FAFF91032449947FC0556198D2FC,与C#代码new Guid("FFFA9208-0391-4924-947F-C0556198D2FC").ToByteArray()生成的字节数组完全一致。
内容的提问来源于stack exchange,提问作者Pavel Kovalev
相关产品推荐
相关产品推荐

