是否可以在MS SQL的WHERE子句中使用IF子句?
例:
1 2 3 4 5
| WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%' |
使用CASE语句
更新:以前的语法(如少数人指出的那样)不起作用。您可以按以下方式使用CASE:
1 2 3 4 5 6
| WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber) = 1 THEN
@OrderNumber
ELSE
'%' + @OrderNumber
END |
或者您可以使用@N这样的IF语句。 J.里德指出。
您应该能够在没有任何IF或CASE的情况下执行此操作
1 2 3 4 5 6
| 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语句。
1 2 3
| WHERE
(IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%') |
在SQL中没有一个很好的方法。我见过一些方法:
1)结合使用CASE和布尔运算符:
1 2 3 4 5 6 7 8 9 10 11 12
| 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
1 2 3 4 5 6 7 8
| 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
第三种方法很丑陋,但是如果您有许多类似的可变条件,它几乎是唯一可行的方法。
使用CASE语句代替IF。
您需要CASE语句
1 2
| WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END |
我认为在...喜欢/ = ...情况下...那么...可以使用布尔值。我正在使用T-SQL。
场景:假设如果bool为假,则要获得Person-30的爱好,如果bool为真,则要获得Person-42的爱好。 (根据某些情况,爱好查找构成了业务计算周期的90%以上,因此请密切注意。)
1 2 3 4 5 6 7 8 9 10 11 12
| CREATE PROCEDURE sp_Case
@bool bit
AS
SELECT Person.Hobbies
FROM Person
WHERE Person.ID =
CASE @bool
WHEN 0
THEN 30
WHEN 1
THEN 42
END; |
1 2 3
| WHERE (IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber)
AND (IsNumber(@OrderNumber) = 1 OR OrderNumber LIKE '%'
+ @OrderNumber + '%') |
1
| WHERE OrderNumber LIKE CASE WHEN IsNumeric(@OrderNumber) = 1 THEN @OrderNumber ELSE '%' + @OrderNumber END |
在情况下,条件将正常工作。
CASE Statement is better option than IF always.
1 2
| 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结束。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 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以测试每个语句。
1 2 3 4 5 6 7 8 9 10 11 12
| 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 |
1 2 3 4 5 6 7 8 9 10
| IF @LstTransDt IS NULL
BEGIN
SET @OpenQty=0
END
ELSE
BEGIN
SELECT @OpenQty=IsNull(SUM(ClosingQty),0)
FROM ProductAndDepotWiseMonitoring
WHERE Pcd=@PCd AND PtpCd=@PTpCd AND TransDt=@LstTransDt
END |
看看是否有帮助。
1 2 3 4 5 6 7
| USE AdventureWorks2012;
GO
IF
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
PRINT 'There are more than 5 Touring-3000 bicycles.'
ELSE PRINT 'There are 5 or less Touring-3000 bicycles.' ;
GO |