将字节数组与sql中的位掩码进行比较

时间:2014-04-15 01:24:36

标签: sql sql-server tsql

我已经使用tsql了很长一段时间但是我从未在WHERE子句中看过二进制文件或oring。现在我正在开发一个可以从应用位掩码中受益的新应用程序。 可以说我有16个产品等级。每个等级由位[]列中的位位置表示。因此A109等级为0000000000000001,B704等级为0000001000000000,等级V64为0100000000000000等。任何等级在其数组列中只能有单个1。现在让我们说我可以在制造过程中将这3个等级中的每个等级相互转换。所以这个搜索的位掩码是0100001000000001。我如何写一个WHERE子句列出所有这3个等级的项目?

4 个答案:

答案 0 :(得分:2)

在您的用户界面中,允许用户选择他喜欢的等级。在幕后,每个等级都映射到一个整数 - 来自MarkD解决方案的评分表。在应用程序中总结这些内容。将总数传递给SP。

SQL:

create procedure dbo.GetMaskedList @mask int = 0;
...
    WHERE BinGrading = @mask;

UI:

int mask = 0;
foreach(item in selectList)
{
    mask += item.BinScore;
}

exec GetMaskedList @mask = mask;

答案 1 :(得分:1)

对我来说也是第一次。有趣。

declare @A109 int = 1;
declare @B704 int = 512;
declare @V64  int = 16384;
declare @Xx   int = 32;

declare @mask int = 16897; --@A109+@B704+@V64

create table #MyData (
    name char(2),
    value int);

insert #MyData
values ('a', @A109), ('b1', @B704), ('b2',@B704), ('c', @Xx);

select
    name,
    value
from #MyData
where (value & @mask) in (@A109, @B704, @V64);

drop table #MyData;

看来你不能对二进制数据进行按位操作! "In a bitwise operation, only one expression can be of either binary or varbinary data type"

答案 2 :(得分:1)

在这种情况下,WHERE子句将非常简单,因为您将处理二进制数的十进制(基数10)对应物......它变得可爱,位于JOIN 。为了澄清,该方法不使用位[]列或BINARY类型 - 仅INT

希望您觉得这很有帮助。

DECLARE @G1 INT = 1,    --  0000001
        @G2 INT = 2,    --  0000010
        @G3 INT = 4,    --  0000100
        @G4 INT = 8,    --  0001000
        @G5 INT = 16,   --  0010000
        @G6 INT = 32,   --  0100000
        @G7 INT = 64    --  1000000

;WITH Grading (Grade, BinScore) AS
(
    SELECT  'G1',   1   UNION ALL
    SELECT  'G2',   2   UNION ALL
    SELECT  'G3',   4   UNION ALL
    SELECT  'G4',   8   UNION ALL
    SELECT  'G5',   16  UNION ALL
    SELECT  'G6',   32  UNION ALL
    SELECT  'G7',   64

) 
,Product (ProductName, BinGrading) AS
(
    SELECT 'Foobar',        73  UNION ALL
    SELECT 'Franglesnap',   3   UNION ALL
    SELECT 'Mebble',        32
)
SELECT *
FROM Product
WHERE BinGrading = (@G1 + @G4 + @G7)
--  Alternatively...
--SELECT *
--FROM Product  P
--JOIN Grading  G   ON P.Bingrading & G.BinScore > 0

答案 3 :(得分:1)

我做了一些更多的研究,最好的解决方案是使用按位AND运算符比较掩码

WHERE mask1 & mask2 <> 0

这很容易,简单而且有凝聚力。