Tsql T-SQL在WHERE子句中使用大小写时的不同比较

Tsql T-SQL在WHERE子句中使用大小写时的不同比较,tsql,case,where,Tsql,Case,Where,我想在where子句中使用不同的比较表达式,但它会提示我无效语法。我之所以要使用它,是因为我想根据类型强制执行评估。若我使用t1.Amount 0和@valueB

我想在where子句中使用不同的比较表达式,但它会提示我无效语法。我之所以要使用它,是因为我想根据类型强制执行评估。若我使用t1.Amount 0和@valueB<0,那个么它似乎不是我试图强加到查询中的表达式。如果第一次评估成功,我不希望执行下面的操作,但是sql中没有短路运算符

DECLARE @name AS VARCHAR(200) = 'super'
DECLARE @valueA AS INT = 1 -- Can be 1 or 2
DECLARE @valueB AS DECIMAL = 0.5

SELECT * FROM TABLE_1 t1 WITH(NOLOCK)
WHERE t1.Name = @name
AND 
CASE WHEN t1.Type = 1 THEN (t1.Amount > 0 AND @valueB < 0)
          ELSE (t1.Amount <= @valueB)
END

你不能那样使用它

试试这个


如果你能进一步阐述你想要实现的目标,我将提供帮助。

Zohar Peled的评论正确地指出,CASE是T-SQL中的一个表达式,而不是控制流语句

您试图做的是:

IF <expression_A> = <value_A> 
THEN <apply_condition_B> 
ELSE <apply_condition_C> 
前面的第一个AND的作用类似于THEN关键字,而OR和第二个AND的组合的作用类似于ELSE关键字

考虑到您的查询,我们得到以下映射:

<expression_A>       = t1.Type 
<value_A>            = 1 
<apply_condition_B>  = (t1.Amount > 0 AND @valueB < 0) 
<apply_condition_C>  = (t1.Amount <= @valueB) 
提示:在实际查询中直接使用这种构造之前,我建议您使用更简单的示例数据来了解它是如何工作的

试试这个

DECLARE @name AS VARCHAR(200) = 'super'
DECLARE @valueA AS INT = 1 -- Can be 1 or 2
DECLARE @valueB AS DECIMAL = 0.5

SELECT *
FROM TABLE_1 t1 WITH (NOLOCK)
WHERE t1.NAME = @name
AND (t1.Type = 1 AND (t1.Amount > 0 AND @valueB < 0)
    OR t1.Type <> 1 AND (t1.Amount <= @valueB))

GO
如果您愿意,也可以使用动态SQL

DECLARE @name AS VARCHAR(200) = 'super'
DECLARE @valueA AS INT = 1 -- Can be 1 or 2
DECLARE @valueB AS DECIMAL = 0.5
DECLARE @SQL VARCHAR(MAX)
DECLARE @Type INT

SELECT TOP 1 @Type = t1.Type
FROM TABLE_1 t1 WITH (NOLOCK)
WHERE t1.NAME = @name

SET @SQL = 'SELECT *
FROM TABLE_1 t1 WITH (NOLOCK)
WHERE t1.NAME = @name'
SET @SQL = CASE 
        WHEN @Type = 1
            THEN @SQL + CHAR(13)+CHAR(10) + '   AND (t1.Amount > 0 AND @valueB < 0)'
        ELSE @SQL + CHAR(13)+CHAR(10) + '   AND (t1.Amount <= @valueB)'
        END

--PRINT @SQL

EXEC (@SQL)
GO

你不能用这样的用例。它不是一个流控件,而是一个表达式。
WHERE t1.Name = @name
AND 
( 
    ( t1.Type  = 1 AND (t1.Amount > 0 AND @valueB < 0) ) 
 OR ( t1.Type != 1 AND (t1.Amount <= @valueB)          ) 
) 
-- Note - this is not fully complete, as it assumes t1.Type is not NULL 
WHERE t1.Name = @name
AND 
( 
    (          t1.Type      = 1 AND (t1.Amount > 0 AND @valueB < 0) ) 
 OR ( COALESCE(t1.Type, 0) != 1 AND (t1.Amount <= @valueB)          ) 
) 
DECLARE @name AS VARCHAR(200) = 'super'
DECLARE @valueA AS INT = 1 -- Can be 1 or 2
DECLARE @valueB AS DECIMAL = 0.5

SELECT *
FROM TABLE_1 t1 WITH (NOLOCK)
WHERE t1.NAME = @name
AND (t1.Type = 1 AND (t1.Amount > 0 AND @valueB < 0)
    OR t1.Type <> 1 AND (t1.Amount <= @valueB))

GO
DECLARE @name AS VARCHAR(200) = 'super'
DECLARE @valueA AS INT = 1 -- Can be 1 or 2
DECLARE @valueB AS DECIMAL = 0.5
DECLARE @SQL VARCHAR(MAX)
DECLARE @Type INT

SELECT TOP 1 @Type = t1.Type
FROM TABLE_1 t1 WITH (NOLOCK)
WHERE t1.NAME = @name

SET @SQL = 'SELECT *
FROM TABLE_1 t1 WITH (NOLOCK)
WHERE t1.NAME = @name'
SET @SQL = CASE 
        WHEN @Type = 1
            THEN @SQL + CHAR(13)+CHAR(10) + '   AND (t1.Amount > 0 AND @valueB < 0)'
        ELSE @SQL + CHAR(13)+CHAR(10) + '   AND (t1.Amount <= @valueB)'
        END

--PRINT @SQL

EXEC (@SQL)
GO