在SQL Server中反汇编标志枚举

Bob*_*Bob 10 .net c# sql-server sql-server-2008

INT在SQL Server数据库中有一个列,它存储与位标志枚举相关的值.例如,如果枚举是:

[Flags()]
public enum UserType
{
    StandardUser = 1,
    Admin = 2,
    SuperUser = 4
}
Run Code Online (Sandbox Code Playgroud)

然后SQL Server中的列可能保持值5.

我需要做的是从另一个表中选择包含其他详细信息的所有行UserType,因此使用值为5的示例,我希望从第二个表中选择ID为1和4的行.

有没有人知道以这种方式打破数字的聪明方法 - 理想情况下,该方法应该在某种程度上递归,因为这是一个非常简单的例子,实际的表/枚举要大得多.

Jon*_*nna 21

为了获得所有行都是真的,设置1,并设置4 ...

SELECT * FROM UserTable
WHERE userType & 5 = 5
Run Code Online (Sandbox Code Playgroud)

要获得所有行,其中至少设置了1或4中的一个...

SELECT * FROM UserTable
WHERE userType & 5 <> 0
Run Code Online (Sandbox Code Playgroud)

当然,我们可以将它与连接结合起来:

SELECT Projects.*
FROM Projects JOIN UserTable
ON userID = UserTable.id
WHERE userType & 5 <> 0
Run Code Online (Sandbox Code Playgroud)

或加入旗帜.其中PermissionSets包含标志,用户必须全部设置:

SELECT UserTable.*
FROM UserTable JOIN PermissionSets
ON UserTable.userType & PermissionSets.userType = PermissionSets.userType
WHERE PermissionSets.id = 42
Run Code Online (Sandbox Code Playgroud)

PermissionSets包含标志,用户必须有一组:

SELECT UserTable.*
FROM UserTable JOIN PermissionSets
ON UserTable.userType & PermissionSets.userType <> 0
WHERE PermissionSets.id = 42
Run Code Online (Sandbox Code Playgroud)

SuperUser为id为93的用户打开该位

UPDATE UserTable
SET userType = userType | 4
WHERE id = 93
Run Code Online (Sandbox Code Playgroud)

SuperUser为ID为93的用户关闭该位

UPDATE UserTable
SET userType = userType & ~4
WHERE id = 93
Run Code Online (Sandbox Code Playgroud)

从用于处理来自C#的ADO.NET(或其他)代码,我们可以将相关的UserType值转换为int 传递给参数而不是发送45显式.

编辑:另请参见按位运算符(Transact-SQL)


Sed*_*glu 14

SELECT * FROM first_table f 
  JOIN second_table s ON s.ID & f.Flags <> 0 
  WHERE f.something = something
Run Code Online (Sandbox Code Playgroud)

这将从second_table中选择与第一个表中给定行上的任何标志匹配的所有行.