문제

Transact-SQL의 비트 마스크를 비교하여 비트가 일치하는지 확인하는 방법이 있습니까? 사용자가 속한 모든 역할에 대한 비트 마스크가있는 사용자 테이블이 있으며,있는 모든 사용자를 선택하고 싶습니다. 어느 제공된 비트 마스크의 역할. 따라서 아래 데이터를 사용하여 6 (디자이너+프로그래머)의 Bitmask 역할은 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

우리가 비트 waise를 수행하고 시험에 반대하는 각 사람을 통과하면 다음을 얻습니다.

        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) 

상기는 결과가 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을 사용하십시오 비트와 운영자 "&"그리고 결과를 0과 비교하십시오. 더 좋은 점은 역할을 정수 열의 비트로 코딩하는 대신 각 역할마다 부울 열을 사용하십시오. 그러면 쿼리는 단순히 디자이너와 프로그래머 친화적 일 것입니다. 역할이 응용 프로그램의 수명 동안 많이 변경 될 것으로 예상되는 경우, 다수의 테이블을 사용하여 사용자와 역할 간의 연관성을 매핑하십시오. 두 대안 모두 비트와 연산자의 존재에 의존하는 것보다 휴대가 가능합니다.

SELECT * FROM UserTable WHERE Roles & 6 > 0

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