有没有在Transact-SQL比较两个位掩码,看看是否有任何位数据匹配的一种方式? 我有与所有角色的位掩码用户属于一个用户表,我想选择所有有任何的供应位掩码角色的用户。 因此,使用下面的数据,6位掩码(设计+程序员)的角色应该选择戴夫,查理和苏珊,但不尼克。
User Table
----------
ID Username Roles
1 Dave 6
2 Charlie 2
3 Susan 4
4 Nick 1
Roles Table
-----------
ID Role
1 Admin
2 Programmer
4 Designer
有任何想法吗? 谢谢。
在回答你的问题是使用按位&
这样的:
SELECT * FROM UserTable WHERE Roles & 6 != 0
该6
可以为要检查任何用户有一个或一个以上的比特位域的任意组合进行交换。 当试图验证此,我通常发现它有助于在二进制写这出手写。 你的用户表看起来像这样:
1 2 4
------------------
Dave 0 1 1
Charlie 0 1 0
Susan 0 0 1
Nick 1 0 0
您的测试(6)是这样的
1 2 4
------------------
Test 0 1 1
如果我们通过每个人做bitwaise和反对的测试中,我们得到这些:
1 2 4
------------------
Dave 0 1 1
Test 0 1 1
Result 0 1 1 (6)
Charlie 0 1 0
Test 0 1 1
Result 0 1 0 (2)
Susan 0 0 1
Test 0 1 1
Result 0 0 1 (4)
Nick 1 0 0
Test 0 1 1
Result 0 0 0 (0)
上述应证明任何记录其结果为不为零具有请求标志之一以上。
编辑:这里的测试用例应该要检查该
with test (id, username, roles)
AS
(
SELECT 1,'Dave',6
UNION SELECT 2,'Charlie',2
UNION SELECT 3,'Susan',4
UNION SELECT 4,'Nick',1
)
select * from test where (roles & 6) != 0 // returns dave, charlie & susan
要么
select * from test where (roles & 2) != 0 // returns Dave & Charlie
要么
select * from test where (roles & 7) != 0 // returns dave, charlie, susan & nick
使用Transact-SQL 位AND运算符 “&”和比较的结果为零。 更妙的是,而不是编码的角色整数列的位,使用布尔列,每一个角色。 然后将查询,简直是设计师与程序员友好。 如果你希望在角色在你的应用程序的生命周期发生很大的变化,然后用许多一对多表映射用户和他们的角色之间的关联。 这两种选择比依靠位与运营商的存在更便携。
SELECT * FROM UserTable WHERE Roles & 6 > 0
SELECT * FROM表WHERE MASK1和MASK2> 0
例:
DECLARE @Mask int
SET @Mask = 6
DECLARE @Users TABLE
(
ID int,
Username varchar(50),
Roles int
)
INSERT INTO @Users (ID, Username, Roles)
SELECT 1, 'Dave', 6
UNION
SELECT 2, 'Charlie', 2
UNION
SELECT 3, 'Susan', 4
UNION
SELECT 4, 'Nick', 1
SELECT * FROM @Users WHERE Roles & @Mask > 0
要查找所有程序员使用:
SELECT * FROM UserTable WHERE Roles & 2 = 2