2012-01-27 10 views
10

Tengo una columna INT en una base de datos de SQL Server que almacena un valor relacionado con una enumeración de indicador de bit. Por ejemplo, si la enumeración es:Desarmado de enumeraciones de marcas de bit en SQL Server

[Flags()] 
public enum UserType 
{ 
    StandardUser = 1, 
    Admin = 2, 
    SuperUser = 4 
} 

después la columna en SQL Server puede contener un valor de 5.

Lo que necesito hacer es seleccionar todas las filas de otra tabla que sostiene detalles adicionales sobre el UserType, así que usando el ejemplo de un valor de 5, me gustaría seleccionar las filas de la segunda tabla con los ID 1 y 4.

¿Alguien conoce una manera ingeniosa de dividir el número de esta manera? el método debe ser recursivo hasta cierto punto, ya que este es un ejemplo muy simplificado, y las tablas/enumeraciones reales son mucho más grandes.

Respuesta

14
SELECT * FROM first_table f 
    JOIN second_table s ON s.ID & f.Flags <> 0 
    WHERE f.something = something 

Esto seleccionaría todas las filas de la segunda tabla que coincida con cualquiera de los indicadores en la fila dada en la primera tabla.

+0

el clavo, gracias :) – Bob

20

Para obtener todas las filas de los que es válido tanto que se pone 1, 4 y que se ajusta ...

SELECT * FROM UserTable 
WHERE userType & 5 = 5 

Para obtener todas las filas de los que es cierto que al menos uno de 1 o 4 se fija ...

SELECT * FROM UserTable 
WHERE userType & 5 <> 0 

Y, por supuesto, podemos combinar esto con une:

SELECT Projects.* 
FROM Projects JOIN UserTable 
ON userID = UserTable.id 
WHERE userType & 5 <> 0 

o unirse en las banderas. Donde PermissionSets contiene banderas y los usuarios deben tener todo el conjunto:

SELECT UserTable.* 
FROM UserTable JOIN PermissionSets 
ON UserTable.userType & PermissionSets.userType = PermissionSets.userType 
WHERE PermissionSets.id = 42 

donde PermissionSets contiene las banderas y los usuarios deben tener un sistema:

SELECT UserTable.* 
FROM UserTable JOIN PermissionSets 
ON UserTable.userType & PermissionSets.userType <> 0 
WHERE PermissionSets.id = 42 

Para activar el bit SuperUser para el usuario con id de 93

UPDATE UserTable 
SET userType = userType | 4 
WHERE id = 93 

para desactivar el bit de SuperUser para el usuario con id de 93

UPDATE UserTable 
SET userType = userType & ~4 
WHERE id = 93 

Desde el ADO.NET (o lo que sea) de código que se utiliza para hacer frente a esto desde C# podemos pasar el elenco UserType valor correspondiente a int en un parámetro en lugar de enviar 4 o 5 explícitamente.

Editar: Véase también, Bitwise Operators (Transact-SQL)

+0

Gracias Jon, explicación súper – Bob

Cuestiones relacionadas