似乎 SQL Server 认为 0x 和 0x00 相等:
SELECT CASE WHEN 0x = 0x00 THEN 1 ELSE 0 END
这输出1
.
如何获得真正的二进制逐位比较行为?另外,两个值被认为相等的确切规则是什么?(var)binary
另请注意以下行为:
--prints just one of the values
SELECT DISTINCT [Data]
FROM (VALUES (0x), (0x00), (0x0000)) x([Data])
--prints the obvious length values 1, 2 and 3
SELECT DATALENGTH([Data]) AS [DATALENGTH], LEN([Data]) AS [LEN]
FROM (VALUES (0x), (0x00), (0x0000)) x([Data])
问题的背景是我正在尝试对二进制数据进行重复数据删除。我需要GROUP BY
二进制数据,而不仅仅是比较两个值。我很高兴我什至注意到了这个问题。
请注意,这HASHBYTES
不支持 LOB。我也想找到一个更简单的解决方案。
我在 BOL 的任何地方都找不到这种比较行为。
但是对于带有右填充零的 varbinary 数据的 Connect Item Invalid 相等性比较表明
连接项还指出尾随零的存在是 SQL Server 与逐字节比较行为不同的唯一情况。
为了区分 SQL Server 中仅通过尾随
0x00
字符不同的两个二进制值,您还可以DATALENGTH
按照问题中的指示添加到比较中。首选
DATALENGTH
而不是LEN
一般的原因是因为后者给出了隐式转换varchar
,然后你就会遇到尾随空格的问题。尽管两者都适用于您的用例。
有趣的是,两个值 0x0 和 0x00 只是相同存储值的不同字符表示。尝试运行以下代码片段向自己证明这一点。
我可以理解为什么零填充会让人们感到惊讶,但这一直是很长一段时间的默认行为,所以我想我已经开始期待它了。
-PatP