是否可以在 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 + '%'
您应该能够在没有任何 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 + '%')
在 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
第三种方法是可怕的,但如果你有许多这样的可变条件,它几乎是唯一可行的方法。
使用CASE语句而不是 IF。
您想要 CASE 语句
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END
我认为 where...like/=...case...then... 可以与布尔值一起使用。我正在使用 T-SQL。
场景:假设如果 bool 为假,您想获得 Person-30 的爱好,如果 bool 为真,您想获得 Person-42 的爱好。(根据一些人的说法,爱好查找占业务计算周期的 90% 以上,因此请密切注意。)
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;
// 使用存储过程选择按国家和站点过滤的用户的示例
CREATE STORED PROCEDURE GetUsers
@CountryId int = null,
@SiteId int = null
AS
BEGIN
SELECT *
FROM Users
WHERE
CountryId = CASE WHEN ISNUMERIC(@CountryId) = 1 THEN @CountryId ELSE CountryId END AND
SiteId = CASE WHEN ISNUMERIC(@SiteId) = 1 THEN @SiteId ELSE SiteId END END
// 从输入 countryId 和/或 siteId 如果存在则不过滤
澄清一些逻辑等价的解决方案。
一个 if 语句
if (a) then b
逻辑上等价于
(!a || b)
这是逻辑等价维基百科文章中涉及条件语句的逻辑等价部分的第一行。
要包含else,您要做的就是添加另一个条件
if(a) then b;
if(!a) then c;
这在逻辑上等价于 (!a || b) && (a || c)
因此以 OP 为例:
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
逻辑等价物是:
(IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber)
AND (IsNumeric(@OrderNumber) = 1 OR OrderNumber LIKE '%' + @OrderNumber + '%' )
WHERE (IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber) AND (IsNumber(@OrderNumber) = 1 OR OrderNumber LIKE '%' + @OrderNumber + '%')
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
WHERE OrderNumber LIKE CASE WHEN IsNumeric(@OrderNumber) = 1 THEN @OrderNumber ELSE '%' + @OrderNumber END
在线路情况下,条件将正常工作。
在sql server中我有同样的问题我只想在参数为false并且为true时才使用and语句我必须同时显示值true和false所以我以这种方式使用它
(T.IsPublic = @ShowPublic or @ShowPublic = 1)
以下示例将查询作为布尔表达式的一部分执行,然后根据布尔表达式的结果执行略有不同的语句块。每个语句块都以 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
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
看看这是否有帮助。
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