设置变量时是否有使用 NOT IN (1,2,3) 语法的紧凑方法?

War*_* P 5 sql-server t-sql

像 NOT IN (1,2,3) 这样的表达式在 where 子句中是有效的:

SELECT foo FROM bar WHERE 
  ((record_type NOT IN (2, 3, 7, 18, 19, 20, 21,12,13,22))
Run Code Online (Sandbox Code Playgroud)

但是,如果我想将一个由上述检查组成的复杂表达式从 WHERE 子句移动到 SET @Var= 语句,有没有办法做到这一点而无需像这样重写它:

declare @record_type int
set  @record_type  = 1

declare @ignoretype bit
IF    (@record_type <> 2)and(@record_type <> 3)and(@record_type <> 7)and
      (@record_type <> 12)and(@record_type <> 13)and
      ( (@record_type < 18) or (@record_type > 22))
     set @ignoretype=1
else
     set @ignoretype=0
Run Code Online (Sandbox Code Playgroud)

我觉得过去适合在一个可读行中的内容现在是一个巨大的混乱,这真的很糟糕。我是否在 SQL 中遗漏了一些与“NOT IN (1,2,3)”等效的语法,这些语法适用于set @var =IF表达式?我会把上面写成:

select @ignoretype = (@record_type <> 2) ....
Run Code Online (Sandbox Code Playgroud)

但是你甚至不能在 Microsoft SQL Server 的 select 语句中使用“<>”不等式,这对于 DBA 和 SQL 专家来说可能是正常情况,但作为一个相对较新的 SQL Server 人,我仍然发现各种语法限制在各种情况下令人困惑。

Mar*_*ith 7

SQL Server 中没有布尔数据类型,这就是为什么select @ignoretype = (@record_type <> 2)不起作用。

IF @record_type NOT IN ( 2, 3, 7, 18, 19, 20, 21, 12, 13, 22 )
  SET @ignoretype=1
ELSE
  SET @ignoretype=0
Run Code Online (Sandbox Code Playgroud)

工作正常。或者你也可以这样做

SET @ignoretype = CASE
                    WHEN @record_type NOT IN ( 2, 3, 7, 18, 19, 20, 21, 12, 13, 22 ) 
                    THEN 1
                    ELSE 0
                  END 
Run Code Online (Sandbox Code Playgroud)

或者(如果您使用的是 2012+)

SET @ignoretype = IIF(@record_type NOT IN ( 2, 3, 7, 18, 19, 20, 21, 12, 13, 22 ) ,1,0)
Run Code Online (Sandbox Code Playgroud)