具有varbinary列的按位AND运算符

时间:2016-01-29 18:12:43

标签: sql sql-server sql-server-2008

使用SQL Server 2008,我有一个varbinary(32)列,最多可显示256个属性。我需要能够识别未选择特定属性的位置。

例如,属性15存储为

0x0080000000000000000000000000000000000000000000000000000000000000

属性14和15存储为

0x00C0000000000000000000000000000000000000000000000000000000000000

因此知道0x00C000 ...具有属性15,我以为我可以使用按位AND运算符来查询打开属性15的所有行:

select * from table where varbinaryCol & 32768 > 0

但是这会返回0行。该表至少有一行,其中属性14 AND 15打开,至少一行仅打开属性15。我希望该查询至少返回2行。

我错过了什么?

修改

以下是具有各种位翻转的列的值的进一步示例:

0:
0x0100000000000000000000000000000000000000000000000000000000000000

32:
0x0000000001000000000000000000000000000000000000000000000000000000

64:
0x0000000000000000010000000000000000000000000000000000000000000000

96:
0x0000000000000000000000000100000000000000000000000000000000000000

所以看起来这个64字节的十六进制字符串中存储了8个单独的十六进制值?

3 个答案:

答案 0 :(得分:0)

是,32768 = 2 ^ 15,但是在二进制文件中,这是第16个标志,因为2 ^ 0 = 1。

我还建议您使用tsql中的power函数来表示这些数字,以便跟在你后面的人不必进行二进制翻译。

SELECT POWER(2,15); -- 32768

答案 1 :(得分:0)

您是否尝试() - 我认为您可能会遇到操作订单问题

select * 
from table 
where (varbinaryCol & 32768) > 0

答案 2 :(得分:0)

此处的问题是类型为varbinary,而不是int

在SQL Server bitwise operations中,不使用两个varbinary值,其中一个必须为int(或smallinttinyintbit)。

您必须使用varbinary将长SUBSTRING拆分为4个字节的块,然后使用int位掩码应用位运算符。

或者,您可以编写CLR函数,该函数使用两个varbinary值。

除此之外,您还需要注意二进制值的存储方式。您32768位掩码值的Endianness是多少。

看起来您的varbinary值对SQL Server使用的内容使用不同的字节序。很容易看到:

SELECT cast(32768 as binary(32))

返回

0x0000000000000000000000000000000000000000000000000000000000008000

所以,你的varbinaryCol & 32768比较

0x0080000000000000000000000000000000000000000000000000000000000000
with
0x0000000000000000000000000000000000000000000000000000000000008000