المقارنة بين اثنين من bitmasks في SQL لمعرفة ما إذا كان أي من أجزاء المباراة

StackOverflow https://stackoverflow.com/questions/143712

  •  02-07-2019
  •  | 
  •  

سؤال

هل هناك طريقة المقارنة بين اثنين من bitmasks في 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 يمكن استبدال أي مزيج من bitfield حيث كنت ترغب في التحقق من أن أي مستخدم واحد أو أكثر من هذه البتات.عند محاولة التحقق من صحة هذه عادة ما تجد أنه من المفيد أن أكتب هذا خارج تخفف الثنائية.المستخدم الخاص بك الجدول يبدو مثل هذا:

        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 المعامل و مشغل "&" ومقارنة النتيجة صفر.حتى أفضل, بدلا من الترميز أدوار كما بت عدد صحيح عمود استخدام منطقية الأعمدة ، واحدة لكل دور.ثم الاستعلام الخاص بك سيكون ببساطة مصمم و مبرمج ودية.إذا كنت تتوقع الأدوار إلى تغيير الكثير على مدى عمر من التطبيق الخاص بك ثم استخدام العديد إلى العديد من طاولة إلى خريطة الرابطة بين المستخدمين و أدوارهم.كل البدائل المحمولة أكثر من الاعتماد على وجود المعامل و المشغل.

SELECT * FROM UserTable WHERE Roles & 6 > 0

SELECT * FROM table 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top