比较二进制 0x 和 0x00 结果在 SQL Server 上相等

usr*_*usr 6 sql-server sql-server-2012 varbinary

似乎 SQL Server 认为 0x 和 0x00 相等:

SELECT CASE WHEN 0x = 0x00 THEN 1 ELSE 0 END
Run Code Online (Sandbox Code Playgroud)

这输出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])
Run Code Online (Sandbox Code Playgroud)

问题的背景是我正在尝试对二进制数据进行重复数据删除。我需要GROUP BY二进制数据,而不仅仅是比较两个值。我很高兴我什至注意到了这个问题。

请注意,它HASHBYTES不支持 LOB。我也想找到一个更简单的解决方案。

Mar*_*ith 6

我找不到 BOL 中任何地方指定的比较行为。

但是 Connect Item Invalid equal Comparison for varbinary data with right padded Zeros指出

基本上,该标准将仅由[尾随] 不同的字符串视为等于或更少,由实现来处理00。我们平等地对待它。

连接项还指出尾随零的存在是 SQL Server 与逐字节比较行为不同的唯一情况。

为了区分 SQL Server 中仅尾随0x00字符不同的两个二进制值,您还可以DATALENGTH按照问题中的指示添加到比较中。

DATALENGTH在这里选择而不是一般的原因LEN是因为后者给出了隐式转换varchar,然后你会遇到尾随空格的问题。

+-------------+--------------------+
| LEN(0x2020) | DATALENGTH(0x2020) |
+-------------+--------------------+
|           0 |                  2 |
+-------------+--------------------+
Run Code Online (Sandbox Code Playgroud)

尽管两者都适用于您的用例。