Ответ 1
SELECT * FROM first_table f
JOIN second_table s ON s.ID & f.Flags <> 0
WHERE f.something = something
Это выберет все строки из second_table, которые соответствуют любому из флагов в данной строке в первой таблице.
У меня есть столбец INT
в базе данных SQL Server, в котором хранится значение, относящееся к перечислению флага бит. Например, если перечисление:
[Flags()]
public enum UserType
{
StandardUser = 1,
Admin = 2,
SuperUser = 4
}
тогда столбец в SQL Server может содержать значение 5.
Что мне нужно сделать, так это выбрать все строки из другой таблицы, содержащие дополнительные сведения о UserType
, поэтому, используя пример значения 5, я хотел бы выбрать строки из второй таблицы с идентификаторами 1 и 4.
Кто-нибудь знает умный способ сломать номер таким образом - в идеале метод должен быть рекурсивным до некоторой степени, поскольку это очень упрощенный пример, а фактические таблицы/перечисления намного больше.
SELECT * FROM first_table f
JOIN second_table s ON s.ID & f.Flags <> 0
WHERE f.something = something
Это выберет все строки из second_table, которые соответствуют любому из флагов в данной строке в первой таблице.
Чтобы получить все строки, для которых это верно, и то, что установлено 1, и что 4 установлено...
SELECT * FROM UserTable
WHERE userType & 5 = 5
Чтобы получить все строки, для которых верно, что установлено хотя бы одно из 1 или 4...
SELECT * FROM UserTable
WHERE userType & 5 <> 0
И, конечно, мы можем объединить это с объединениями:
SELECT Projects.*
FROM Projects JOIN UserTable
ON userID = UserTable.id
WHERE userType & 5 <> 0
Или присоединение к флагам. Где PermissionSet содержит флаги, а пользователи должны иметь все:
SELECT UserTable.*
FROM UserTable JOIN PermissionSets
ON UserTable.userType & PermissionSets.userType = PermissionSets.userType
WHERE PermissionSets.id = 42
Где PermissionSets содержит флаги, а пользователи должны иметь один набор:
SELECT UserTable.*
FROM UserTable JOIN PermissionSets
ON UserTable.userType & PermissionSets.userType <> 0
WHERE PermissionSets.id = 42
Чтобы включить бит SuperUser
для пользователя с идентификатором 93
UPDATE UserTable
SET userType = userType | 4
WHERE id = 93
Чтобы отключить бит SuperUser
для пользователя с идентификатором 93
UPDATE UserTable
SET userType = userType & ~4
WHERE id = 93
Из кода ADO.NET(или любого другого), который используется для решения этой проблемы с С#, мы можем передать соответствующее значение UserType
, отличное от int, вместо отправки 4
или 5
явно.
Изменить: см. также Побитовые операторы (Transact-SQL)