SQL Server按位操作像C#枚举标志

前端之家收集整理的这篇文章主要介绍了SQL Server按位操作像C#枚举标志前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用C#中的枚举的标志,一切都很好,但是想在以下情况下使用类似sql的东西:

我们希望返回列表中列出的用户列表或条件如下所示:

ConditionOne = 2
ConditionTwo = 4
ConditionThree = 8

等等…

我们将为用户提供一些这样的条件反对他们:

User1: 6 (conditions 1 and 2)
User2: 4 (condition 2)
User3: 14 (conditions 1,2 and 3)

等等…

我们希望能够做一个查询,在这里我们会说所有使用条件1的用户,而且在这种情况下,即使他们有其他条件,它也会返回用户1和3.

任何洞察将不胜感激,只使用C#中的标志,而不直接在sql Server中使用.

解决方法

虽然James所建议的按位操作符会奏效,但在关系数据库中并不会很好,尤其是当您尝试扩展到数百万条记录时.原因是where子句中的函数是不可用的(它们阻止索引查找).

我会做的是创建一个包含所有可能的标志和条件组合的表,这将使索引在该条件下寻找.

填充FlagConditions.我用了一个(tinyint).如果你需要更多的标志,你应该能够扩展这种方法

CREATE TABLE FlagConditions (
      Flag TINYINT,Condition TINYINT,CONSTRAINT Flag_Condition PRIMARY KEY CLUSTERED (Condition,Flag)
);

CREATE TABLE #Flags (
      Flag TINYINT IDENTITY(0,1) PRIMARY KEY CLUSTERED,DummyColumn BIT NULL);
GO

INSERT #Flags
        ( DummyColumn )
SELECT NULL;
GO 256

CREATE TABLE #Conditions(Condition TINYINT PRIMARY KEY CLUSTERED);

INSERT #Conditions ( Condition )
    VALUES  (1),(2),(4),(8),(16),(32),(64),(128);

INSERT FlagConditions ( Flag,Condition )        
    SELECT
    Flag,Flag & Condition
    FROM #Flags f
    CROSS JOIN #Conditions c
    WHERE Flag & Condition <> 0;

DROP TABLE #Flags;
DROP TABLE #Conditions;

现在,您可以随时使用FlagConditions表,以便有效地寻找枚举位置条件:

DECLARE @UserFlags TABLE (Username varchar(10),Flag tinyint);

INSERT @UserFlags(Username,Flag)
    VALUES ('User1',6),('User2',4),('User3',14);

DECLARE @Condition TINYINT = 2;

SELECT u.*
FROM @UserFlags u
INNER JOIN FlagConditions fc ON u.Flag = fc.Flag
WHERE fc.Condition = @Condition;

这返回:

Username   Flag
---------- ----
User1      6
User3      14

你的DBA会感谢你去这个面向路线的路线.

猜你在找的MsSQL相关文章