有没有办法比较Transact-SQL中的两个位掩码,看看是否有任何匹配的位?我有一个User表,其中包含用户所属角色的位掩码,我想选择所有在提供的位掩码中具有任何角色的用户.因此,使用下面的数据,角色位6(设计师+程序员)应选择Dave,Charlie和Susan,但不能选择Nick.
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
有任何想法吗?谢谢.
您的问题的答案是&
像这样使用Bitwise :
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运算符 "&"并将结果与零进行比较.更好的是,不要将角色编码为整数列的位,而是使用布尔列,每个角色一个.然后你的查询只是设计师和程序员友好.如果您希望角色在应用程序的生命周期内发生很大变化,那么请使用多对多表来映射用户与其角色之间的关联.两种替代方案都比依赖于按位AND运算符的存在更具可移植性.
SELECT * FROM UserTable WHERE Roles & 6 > 0