我在SQL Server数据库中有一个INT
列,它存储与位标志枚举相关的值。例如,如果枚举是:
[Flags()]
public enum UserType
{
StandardUser = 1,
Admin = 2,
SuperUser = 4
}
然后SQL Server中的列可能保存值为5。
我需要做的是从另一个表中选择所有行,其中包含有关UserType
的其他详细信息,因此使用值为5的示例,我希望从第二个表中选择行ID 1和4。
有没有人知道以这种方式打破数字的聪明方法 - 理想情况下,该方法应该在某种程度上递归,因为这是一个非常简化的示例,并且实际的表/枚举要大得多。
答案 0 :(得分:21)
要获得设置为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
或加入旗帜。其中PermissionSets包含标志,用户必须全部设置:
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
为身份为93
的用户启用SuperUser
位
UPDATE UserTable
SET userType = userType | 4
WHERE id = 93
要为ID为93
的用户关闭SuperUser
位
UPDATE UserTable
SET userType = userType & ~4
WHERE id = 93
从用于处理C#的ADO.NET(或其他)代码中,我们可以将相关的UserType
值转换为int传递给参数,而不是发送4
或{{ 1}}明确。
答案 1 :(得分:14)
SELECT * FROM first_table f
JOIN second_table s ON s.ID & f.Flags <> 0
WHERE f.something = something
这将从second_table中选择与第一个表中给定行上的任何标志匹配的所有行。