Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server按位处理,如C#枚举标志_Sql_Sql Server_Bitwise Operators - Fatal编程技术网

SQL Server按位处理,如C#枚举标志

SQL Server按位处理,如C#枚举标志,sql,sql-server,bitwise-operators,Sql,Sql Server,Bitwise Operators,如何在SQL Server中使用诸如C#中的枚举上的标记处理 例如,如何返回作为列表或类似条件一部分的用户列表: ConditionAlpha = 2 ConditionBeta = 4 ConditionGamma = 8 然后,会有一些用户遇到以下情况: User1: 6 (conditions Alpha and Beta) User2: 4 (condition Beta) User3: 14 (conditions Alpha, Beta and Gamma) 我们希望能够

如何在SQL Server中使用诸如C#中的枚举上的标记处理


例如,如何返回作为列表或类似条件一部分的用户列表:

ConditionAlpha = 2
ConditionBeta  = 4
ConditionGamma = 8

然后,会有一些用户遇到以下情况:

User1: 6 (conditions Alpha and Beta)
User2: 4 (condition Beta)
User3: 14 (conditions Alpha, Beta and Gamma)


我们希望能够执行一个查询,其中我们说获取具有第一个条件Alpha的所有用户,在这种情况下,它将返回用户1和3,即使他们还有其他条件。

检查SQL中是否设置了标志的按位运算符是
&
WHERE
子句需要计算为
BOOLEAN
表达式,如下所示:

create table #temp (id int, username varchar(20), flags int)

insert into #temp values
(1, 'User1', 6 /* (2 | 4) */),
(2, 'User2', 4),
(3, 'User3', 14 /* (2 | 4 | 8) */)

declare @ConditionOne int = 2

select *
from   #temp
where  flags & @ConditionOne <> 0

declare @ConditionTwo int = 4

select *
from   #temp
where  flags & @ConditionTwo <> 0

declare @ConditionThree int = 8

select *
from   #temp
where  flags & @ConditionThree <> 0

drop table #temp

虽然James建议的按位运算符可以工作,但在关系数据库中,它的性能不是很好,特别是当您试图扩展到数百万条记录时。原因是where子句中的函数不可用(它们阻止索引查找)

我要做的是创建一个表,其中包含所有可能的标志和条件组合,这将启用对条件的索引搜索

填充条件。我用了一个(罐头)。如果您需要更多标志,您应该能够扩展此方法:

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;
这将返回:

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

您的DBA将感谢您选择这种面向集合的路线。

我遇到了几乎相同的问题,可以提出这样的解决方案:

SELECT  t.value
    , ISNULL(t.C1 + ', ', '') + ISNULL(t.C2, '') + ISNULL(', ' + t.C3, '') AS [type]
FROM
(
    SELECT value,
        CASE WHEN (type & 2) <> 0  THEN 'Type1' END AS C1,
         CASE WHEN (type & 4) <> 0  THEN 'Type2' END AS C2,
         CASE WHEN (type & 8) <> 0  THEN 'Type3' END AS C3
    FROM db.Agent
) t

C#Enum:
CopEntry=1将此信息存储在多对多表中更像“SQL”。因此,您需要将行
(1,1)、(1,2)、(2,2)、(3,1)、(3,2)、(3,3)
存储在单独的表中。这将有助于更自然的查询,并提供索引机会。我不明白当这个答案包含的SQL实际上甚至没有解析(“GO256”)时,它怎么会有20次投票。即使在删除256之后,它也不会执行答案所说的操作。@IanKemp这将在SSMS或sqmcmd中工作。GO不是一个T-SQL语句,而是一个批处理分隔符。它被诸如SSMS之类的sql工具识别。它的语法是
GO[count]
,其中count是运行前一批的次数。因此,在本例中,它将运行insert 256次。docselegant但是如果你需要在两个或更多的条件下进行过滤呢?你会为每个条件做额外的连接吗?
Username   Flag
---------- ----
User1      6
User3      14
SELECT  t.value
    , ISNULL(t.C1 + ', ', '') + ISNULL(t.C2, '') + ISNULL(', ' + t.C3, '') AS [type]
FROM
(
    SELECT value,
        CASE WHEN (type & 2) <> 0  THEN 'Type1' END AS C1,
         CASE WHEN (type & 4) <> 0  THEN 'Type2' END AS C2,
         CASE WHEN (type & 8) <> 0  THEN 'Type3' END AS C3
    FROM db.Agent
) t
value       type
----------  ------------------------------------
14          Type1, Type2, Type3
12          Type2, Type3
14          Type1, Type2, Type3