如何将C#字节数组构造Guid的代码转为SQL Server标量函数?
在T-SQL中实现通过指定字节数组生成Guid(等价于C#的
new Guid(byte[])) 在把C# CLR代码转换为SQL Server存储过程和标量函数时,碰到了一段用16字节数组生成Guid的逻辑(对应的C#代码如下),但SQL Server自带的NEWID()仅能生成随机Guid,无法满足从指定字节数组生成Guid的需求。
对应的C#代码:
public static Guid GenerateGuid() { var bytes = GenerateBytes(); return new Guid(bytes); }
可以通过自定义标量函数实现该需求,需要注意:C#和SQL Server对Guid字节顺序的处理存在差异,必须调整字节顺序才能得到和C#完全一致的结果。
自定义标量函数实现
创建dbo.ConvertBytesToGuid函数,接受16字节的二进制参数,返回对应的Guid:
CREATE FUNCTION dbo.ConvertBytesToGuid(@Bytes VARBINARY(16)) RETURNS UNIQUEIDENTIFIER AS BEGIN -- 校验输入必须是16字节 IF LEN(@Bytes) <> 16 RETURN NULL; -- 调整字节顺序匹配C# new Guid(byte[])的行为 RETURN CONVERT(UNIQUEIDENTIFIER, SUBSTRING(@Bytes, 4, 1) + SUBSTRING(@Bytes, 3, 1) + SUBSTRING(@Bytes, 2, 1) + SUBSTRING(@Bytes, 1, 1) + SUBSTRING(@Bytes, 6, 1) + SUBSTRING(@Bytes, 5, 1) + SUBSTRING(@Bytes, 8, 1) + SUBSTRING(@Bytes, 7, 1) + SUBSTRING(@Bytes, 9, 8) ); END;
使用示例
假设你有16字节的二进制数据0x000102030405060708090A0B0C0D0E0F,调用函数即可生成和C#代码一致的Guid:
SELECT dbo.ConvertBytesToGuid(0x000102030405060708090A0B0C0D0E0F) AS GeneratedGuid;
执行结果为:03020100-0504-0706-0809-0A0B0C0D0E0F,和C# new Guid(byte[])生成的结果完全匹配。
额外说明
- 如果不需要严格对齐C#的字节顺序,只是单纯将16字节转成Guid,可以直接用
CONVERT(UNIQUEIDENTIFIER, @Bytes),但生成的Guid会和C#的结果不同; - 函数会校验输入长度,非16字节的输入会返回NULL。
内容的提问来源于stack exchange,提问作者Lord Yggdrasill
相关产品推荐
相关产品推荐

