首页 > 解决方案 > 在 HashByte md5 函数中使用 varchar(8000) 列值

问题描述

我想使用 SQL 中的所有行值创建一个哈希。在该表中,列长度之一是 varchar(8000)。我放置了一个如下所示的 hashbyte 函数 -

Hashbyte('MD5',column1+column2+....) -- column1 having varchar(8000) length and it contains string of length 8000.

然后它给了我相同的哈希字节,即使其他列包含不同的数据,column1 中具有相同值的行也是如此

然后我在 hashbyte 函数中将 column1 转换为 varchar(max),每行得到不同的 hashbyte。

Hashbyte('MD5',convert(varchar(max),column1)+column2+....)

为什么 hashbyte('MD5'...) 不会采用所有列值?

如果您想再尝试一个 varchar(8000) 列问题的示例,请尝试计算长度

创建一个包含 varchar(8000) 列的表并计算所有列值的长度。它只会给你8000。接下来将 varchar(8000) 转换为 varchar(max) 它会给你正确的结果。

len(column1+column2...) --> 8000
len(convert(varchar(max),column1)+column2...) --> actual length

用 varchar(8000) 添加任何字符串是这样的问题吗?

标签: sql-server

解决方案


您误以为 avarchar(8000)连接到 a varchar(8000)(甚至任何其他长度<= 8000)会导致 a varchar(MAX)。这不是真的。要获得MAX长度,您必须将表达式中的至少一个值定义为MAX.

这在+ (String Concatenation) (Transact-SQL)的注释中得到证实:

评论

...

如果字符串连接的结果超过 8,000 字节的限制,则结果将被截断。但是,如果连接的字符串中至少有一个是大值类型,则不会发生截断。

因此,您需要先将其中一个值转换为MAX,然后将其余的值也隐式转换为 a MAX。如果您没有显式转换(至少)其中一个表达式,那么该值将被截断,如文档所述。

显然这也适用于nvarchar截断发生在 4,000 个字符(仍然是 8,000 个字节)的情况。


推荐阅读