【问题标题】:Hashing more than 8000 bytes in SQL Server在 SQL Server 中散列超过 8000 个字节
【发布时间】:2011-12-07 21:19:04
【问题描述】:

SQL Server 的散列函数 HASHBYTES 的输入限制为 8000 字节。

你如何散列更大的字符串?

【问题讨论】:

    标签: sql-server sql-server-2008 tsql sqlclr


    【解决方案1】:

    您可以散列输入的 8k(或 4k 或 2k)块,然后将这些散列连接起来或将它们散列成一个新的散列值。如果您必须创建一个类似的算法(例如在外部 .NET 应用程序中)来比较在 SQL Server 之外创建的哈希,这可能会变得很困难。

    另一种选择:依靠 SQL Server 的 CLR integration 并在 .NET 程序集中执行散列。

    【讨论】:

    • 感谢 Paul,这是一个非常适合内部使用的解决方案。但在这种情况下,它必须完全符合 sha1
    • @SDReyes:我的回答中添加了另一个想法:依靠 SQL Server 的 CLR 集成并在 .NET 程序集中执行散列。
    • 此答案中的 CLR 集成链接已损坏。
    【解决方案2】:

    与 Paul 的想法一样,想到分块的一个想法是将散列字符串存储在 XML 列中,每个块都作为一个单独的 XML 元素。

    【讨论】:

    • +1 好主意,但为了数据完整性,我建议存储一个散列值(散列的散列)。使用 XML 结构,您需要一个将散列值映射到的额外属性被散列的第 N 个数据块的索引。
    【解决方案3】:

    你可以写一个 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 时才需要。

    【讨论】:

    • 小心 CLR SP 参数被静默截断为 8000 字节 - 我必须用 [SqlFacet(MaxSize = -1)] 标记参数,否则 8000 之后的字节将被忽略!我花了一段时间才拿到那个!
    • -1 误导读者(当然是无意的)使用 UTF-8。 SQL Server(和一般的 Windows)使用 UTF-16。因此,这似乎适用于目前仅使用代码点 0 - 127 或可能高达 256 的许多人。但使用 UTF-8 会导致诸如以下问题之类的问题:SQL CLR function based on .net ComputeHash is not working with Cyrrilic
    • @randomdude 您的体验是由于旧版本的 SSDT 如何生成 T-SQL 包装器对象。默认使用NVARCHAR(4000) 表示SqlStringNVARCHAR(MAX) 表示SqlChars。但由于在 Visual Studio 2013 左右,默认值已更改为对两者都使用 NVARCHAR(MAX)。尽管如此,正如您提到的那样,明确并使用[SqlFacet()] 总是更好,但使用较新SSDT 版本的人不会遇到这种情况。此外,SQLCLR 仅支持NVARCHAR,因此它实际上会在 4000 个字符处截断 :-)。
    猜你喜欢
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多