【发布时间】:2011-12-07 21:19:04
【问题描述】:
SQL Server 的散列函数 HASHBYTES 的输入限制为 8000 字节。
你如何散列更大的字符串?
【问题讨论】:
标签: sql-server sql-server-2008 tsql sqlclr
SQL Server 的散列函数 HASHBYTES 的输入限制为 8000 字节。
你如何散列更大的字符串?
【问题讨论】:
标签: sql-server sql-server-2008 tsql sqlclr
您可以散列输入的 8k(或 4k 或 2k)块,然后将这些散列连接起来或将它们散列成一个新的散列值。如果您必须创建一个类似的算法(例如在外部 .NET 应用程序中)来比较在 SQL Server 之外创建的哈希,这可能会变得很困难。
另一种选择:依靠 SQL Server 的 CLR integration 并在 .NET 程序集中执行散列。
【讨论】:
与 Paul 的想法一样,想到分块的一个想法是将散列字符串存储在 XML 列中,每个块都作为一个单独的 XML 元素。
【讨论】:
你可以写一个 SQL CLR 函数:
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlBinary BigHashBytes(SqlString algorithm, SqlString data)
{
var algo = HashAlgorithm.Create(algorithm.Value);
var bytes = Encoding.UTF8.GetBytes(data.Value);
return new SqlBinary(algo.ComputeHash(bytes));
}
然后在SQL中可以这样调用:
--these return the same value
select HASHBYTES('md5', 'test stuff')
select dbo.BigHashBytes('md5', 'test stuff')
BigHashBytes 仅在长度超过 8k 时才需要。
【讨论】:
[SqlFacet(MaxSize = -1)] 标记参数,否则 8000 之后的字节将被忽略!我花了一段时间才拿到那个!
NVARCHAR(4000) 表示SqlString 和NVARCHAR(MAX) 表示SqlChars。但由于在 Visual Studio 2013 左右,默认值已更改为对两者都使用 NVARCHAR(MAX)。尽管如此,正如您提到的那样,明确并使用[SqlFacet()] 总是更好,但使用较新SSDT 版本的人不会遇到这种情况。此外,SQLCLR 仅支持NVARCHAR,因此它实际上会在 4000 个字符处截断 :-)。