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