是否可以在MS SQL 的WHERE子句中使用IF子句?
例:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
是否可以在MS SQL 的WHERE子句中使用IF子句?
例:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
Answers:
使用CASE语句
UPDATE:先前的语法(如少数人指出的那样)不起作用。您可以按以下方式使用CASE:
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber) = 1 THEN
@OrderNumber
ELSE
'%' + @OrderNumber
END
或者您可以使用@ NJ Reed指出的IF语句。
CASE
在大多数情况下,使用是合适的解决方案。就我而言,我想更改比较运算符,因此我使用了下一种方法。
您应该能够在没有任何IF或CASE的情况下执行此操作
WHERE
(IsNumeric(@OrderNumber) AND
(CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
OR
(NOT IsNumeric(@OrderNumber) AND
OrderNumber LIKE ('%' + @OrderNumber))
根据SQL的风格,您可能需要根据是否支持隐式强制转换将订单号的强制转换调整为INT或VARCHAR。
这是WHERE子句中非常常见的技术。如果要在WHERE子句中应用某些“ IF”逻辑,您需要做的就是将带有布尔AND的额外条件添加到需要应用它的部分。
您根本不需要IF语句。
WHERE
(IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')
where (@AdmUserId is null or CurrentOrder.CustomerAdmUserId = @AdmUserId)
下进行过滤:或者仅在IncludeDeleted = 0时进行过滤: where (@IncludeDeleted = 1 or ItemObject.DeletedFlag = 0)
在SQL中没有一个很好的方法来执行此操作。我见过一些方法:
1)结合使用CASE和布尔运算符:
WHERE
OrderNumber = CASE
WHEN (IsNumeric(@OrderNumber) = 1)
THEN CONVERT(INT, @OrderNumber)
ELSE -9999 -- Some numeric value that just cannot exist in the column
END
OR
FirstName LIKE CASE
WHEN (IsNumeric(@OrderNumber) = 0)
THEN '%' + @OrderNumber
ELSE ''
END
2)在SELECT之外使用IF
IF (IsNumeric(@OrderNumber)) = 1
BEGIN
SELECT * FROM Table
WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
SELECT * FROM Table
WHERE OrderNumber LIKE '%' + @OrderNumber
END
3)使用长字符串,有条件地编写SQL语句,然后使用EXEC
第三种方法令人毛骨悚然,但是如果您有许多类似的可变条件,它几乎是唯一可行的方法。
IF...ELSE...
条件转换为boolean AND
和OR
,就像上面的@ njr101答案中一样。不利的一面IF
是,如果您有很多嵌套,或者嵌套的嵌套很多,则很难做到这一点
在哪里(IsNumeric(@OrderNumber)<> 1 OR OrderNumber = @OrderNumber) AND(IsNumber(@OrderNumber)= 1 OR OrderNumber像'%' + @OrderNumber +'%')
IF P THEN Q ELSE R
<=>
( ( NOT P ) OR Q ) AND ( P OR R )
CASE语句总是比IF更好的选择。
WHERE vfl.CreatedDate >= CASE WHEN @FromDate IS NULL THEN vfl.CreatedDate ELSE @FromDate END
AND vfl.CreatedDate<=CASE WHEN @ToDate IS NULL THEN vfl.CreatedDate ELSE @ToDate END
下面的示例将查询作为布尔表达式的一部分执行,然后根据布尔表达式的结果执行稍有不同的语句块。每个语句块均以BEGIN开头,以END结束。
USE AdventureWorks2012;
GO
DECLARE @AvgWeight decimal(8,2), @BikeCount int
IF
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
BEGIN
SET @BikeCount =
(SELECT COUNT(*)
FROM Production.Product
WHERE Name LIKE 'Touring-3000%');
SET @AvgWeight =
(SELECT AVG(Weight)
FROM Production.Product
WHERE Name LIKE 'Touring-3000%');
PRINT 'There are ' + CAST(@BikeCount AS varchar(3)) + ' Touring-3000 bikes.'
PRINT 'The average weight of the top 5 Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.';
END
ELSE
BEGIN
SET @AvgWeight =
(SELECT AVG(Weight)
FROM Production.Product
WHERE Name LIKE 'Touring-3000%' );
PRINT 'Average weight of the Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.' ;
END ;
GO
使用嵌套的IF ... ELSE语句以下示例说明如何将IF…ELSE语句嵌套在另一个语句中。将@Number变量设置为5、50和500以测试每个语句。
DECLARE @Number int
SET @Number = 50
IF @Number > 100
PRINT 'The number is large.'
ELSE
BEGIN
IF @Number < 10
PRINT 'The number is small'
ELSE
PRINT 'The number is medium'
END ;
GO
在sql server中,我有一个同样的问题,我只想在参数为false时使用and语句,并且在true时必须同时显示true和false值,因此我以这种方式使用它
(T.IsPublic = @ShowPublic or @ShowPublic = 1)